/**
 @file sys_at_serdes.c

 @author  Copyright (C) 2021 Centec Networks Inc.  All rights reserved.

 @date 2021-03-10

 @version v2.0

*/
/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "sys_usw_chip.h"
#include "sys_usw_dmps.h"
#include "sys_usw_datapath.h"
#include "sal.h"
#include "ctc_port.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_interrupt.h"
#include "ctc_warmboot.h"
#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "sys_at_datapath.h"
#include "sys_usw_dmps_db.h"
#include "sys_at_mac.h"
#include "sys_usw_common.h"
#include "sys_at_serdes_fw.inc"
//#include "sys_at_serdes_fw_dbg.inc"
#include "sys_at_serdes.h"

#include "sys_usw_peri.h"
#include "sys_usw_stats_api.h"
#include "sys_usw_dmps.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_port.h"
#include "sys_usw_mac.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_mcu.h"
#include "sys_usw_register.h"

#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "sys_usw_register.h"

extern sal_file_t g_tm_dump_fp;
extern uint8 g_dmps_dbg_sw;
extern sys_datapath_master_t* p_usw_datapath_master[];
#define DRV_IOW_FIELD_NZ(core_id, pp_id, dp_id, lchip, memid, inst_id, fieldid, value, ptr) \
    do\
    {\
        int32 retv = 0;\
        char   fld_str[64] = {0};\
        retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
        if (retv < 0)\
        {\
            return(retv); \
        }\
        drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
        if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw))\
        {\
            if ((255 != pp_id) && (255 != dp_id))\
            {\
                sal_fprintf(g_tm_dump_fp, "write %-35s 0 %-45s 0x%x inst %-5d core %u pp %u dp %u\n", \
                TABLE_NAME(lchip, memid), fld_str, *value, inst_id, core_id, pp_id, dp_id); \
            }\
            else if ((255 != pp_id))\
            {\
                sal_fprintf(g_tm_dump_fp, "write %-35s 0 %-45s 0x%x inst %-5d core %u pp %u\n", \
                TABLE_NAME(lchip, memid), fld_str, *value, inst_id, core_id, pp_id); \
            }\
            else\
            {\
                sal_fprintf(g_tm_dump_fp, "write %-35s 0 %-45s 0x%x inst %-5d core %u\n", \
                TABLE_NAME(lchip, memid), fld_str, *value, inst_id, core_id); \
            }\
        }\
    }\
    while(0)

#if defined(_SAL_LINUX_KM)
#define UINT64_PRINT_FMT_LU
#endif


///////////////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
    uint8  is_valid;
    uint16 serdes_id;
    uint8  ip_type; /*sys_at_serdes_type_t*/
    uint8  init_speed; /*sys_datapath_serdes_speed_t*/
    uint8  ds_speed; /*sys_datapath_serdes_speed_t*/
    uint8  anlt_en; /*1-enable ANLT  0-disable*/
    uint8  lpbk_int_en; /*1-enable  0-disable*/
    uint8  lpbk_ext_en; /*1-enable  0-disable*/
    uint8  prbs_tx_en; /*1-enable  0-disable*/
    uint8  prbs_rx_en; /*1-enable  0-disable*/
} sys_at_serdes_temp_soft_table_t;

sys_at_serdes_temp_soft_table_t temp_soft_table[8] = 
{
    {1, 16, SYS_AT_SERDES_112G, SERDES_SPEED_106_25G, SERDES_SPEED_10_3125G, 1, 1, 1, 1, 1},
    {1, 17, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 1, 1, 1, 1},
    {1, 18, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 1, 1, 1, 1},
    {1, 19, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 1, 1, 1, 1},
    {0, 20, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 0, 0, 0, 0},
    {0, 21, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 0, 0, 0, 0},
    {0, 22, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 0, 0, 0, 0},
    {0, 23, SYS_AT_SERDES_112G, SERDES_SPEED_25_78125G, SERDES_SPEED_53_125G, 1, 0, 0, 0, 0},
};

extern int32
_sys_at_datapath_get_port_chan_by_serdes(uint8 lchip, uint16 logic_serdes, uint16* p_chan, uint16* p_dport);
extern uint32
_sys_at_datapath_get_serdes_support_speed_bmp(uint8 lchip, uint8 chip_type, uint16 logic_serdes);
extern uint32
sys_at_datapath_dic_by_chip_type(uint8 lchip, const sys_at_dmps_id_dictionary_t** p_dic_pointer);
extern int32
_sys_usw_port_api_set_serdes_mode(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info);
extern int32
_sys_at_mac_set_nw_config_by_mac_id(uint8 lchip, uint16 mac_id);
extern uint8
_sys_at_mac_is_power_up(uint8 lchip, uint8 core_id, uint8 mac_group_id, uint8 is_nw);
extern int32
_sys_at_datapath_check_core_pll_lock(uint8 lchip, uint8 core_id);
extern uint8 
_sys_at_datapath_get_serdes_type(uint16 logic_serdes);
extern int32
_sys_at_serdes_get_data_width(sys_at_serdes_dev_t* p_dev, uint16* p_txwidth, uint16* p_rxwidth);
extern int32
_sys_at_serdes_set_trx_en(uint8 lchip, void* p_value);
extern int32
_sys_at_serdes_get_trx_en(uint8 lchip, void* p_value);
extern int32
_sys_at_serdes_get_training_status(sys_at_serdes_dev_t* p_dev, uint16* p_status);
extern int32
_sys_at_serdes_get_sq_det(sys_at_serdes_dev_t* p_dev, uint32* p_sq_det);
void _sys_at_serdes_to_dev(uint8 lchip, uint16 serdes_id, uint8 type, sys_at_serdes_dev_t* p_dev)
{
    p_dev->type = type;
    p_dev->lchip = lchip;
    p_dev->serdes_id = serdes_id;
}

void _sys_at_get_serdes_dev(uint8 lchip, uint16 serdes_id, sys_at_serdes_dev_t* p_dev)
{
    p_dev->type = _sys_at_datapath_get_serdes_type(serdes_id);
    p_dev->lchip = lchip;
    p_dev->serdes_id = serdes_id;
}

#ifdef EMULATION_ENV
uint32
_sys_at_milli_rand(uint32 n)
{
    uint32 rnum = sal_rand() % 1000;
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "#random gen %u, thrd %u\n", rnum, n);
    return rnum < n ? 1 : 0;
}
#endif


///////////////////////////////////////////////////////////////////////////////////////////////

int32
_sys_at_serdes_get_logic_by_physic_serdes(uint8 lchip, uint16 physic_serdes, uint16* p_logic_serdes)
{
    SYS_USW_VALID_PTR_WRITE(p_logic_serdes, physic_serdes);

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_physic_by_logic_serdes(uint8 lchip, uint16 logic_serdes, uint16* p_physic_serdes)
{
    SYS_USW_VALID_PTR_WRITE(p_physic_serdes, logic_serdes);

    return CTC_E_NONE;
}

int32
_sys_at_serdes_valid_check(uint8 lchip, uint16 physic_serdes)
{
    uint16 logic_serdes = 0;

    CTC_ERROR_RETURN(_sys_at_serdes_get_logic_by_physic_serdes(lchip, physic_serdes, &logic_serdes));
    SYS_CONDITION_RETURN((SYS_AT_USELESS_ID16 == logic_serdes), CTC_E_INVALID_PARAM);
    
    return CTC_E_NONE;
}

uint8 _sys_at_serdes_get_related_serdes_speed(uint8 txrx_speed, uint8 type)
{
    uint8 serdes_speed = 0;
    if(SYS_AT_SERDES_56G == type)
    {
        switch(txrx_speed)
        {
            case AT56G_SERDES_1P25G   :
                serdes_speed = SERDES_SPEED_1_25G;
                break;
            case AT56G_SERDES_3P125G  :
                serdes_speed = SERDES_SPEED_3_125G;
                break;
            case AT56G_SERDES_10P3125G:
                serdes_speed = SERDES_SPEED_10_3125G;
                break;
            case AT56G_SERDES_12P5G   :
                serdes_speed = SERDES_SPEED_12_5G;
                break;
            case AT56G_SERDES_25P7812G:
                serdes_speed = SERDES_SPEED_25_78125G;
                break;
            case AT56G_SERDES_26P5625G:
                serdes_speed = SERDES_SPEED_26_5625G;
                break;
            case AT56G_SERDES_28P125G :
                serdes_speed = SERDES_SPEED_28_125G;
                break;
            case AT56G_SERDES_51P5625G:
                serdes_speed = SERDES_SPEED_51_5625G;
                break;
            case AT56G_SERDES_53P125G :
                serdes_speed = SERDES_SPEED_53_125G;
                break;
            case AT56G_SERDES_56P25G  :
                serdes_speed = SERDES_SPEED_56_25G;
                break;
            case AT56G_SERDES_1P0625G :
            case AT56G_SERDES_1P2288G :
            case AT56G_SERDES_2P02752G:
            case AT56G_SERDES_2P125G  :
            case AT56G_SERDES_2P4576G :
            case AT56G_SERDES_2P5G    :
            case AT56G_SERDES_2P57812G:
            case AT56G_SERDES_4P08804G:
            case AT56G_SERDES_4P25G   :
            case AT56G_SERDES_4P9152G :
            case AT56G_SERDES_5G      :
            case AT56G_SERDES_5P15625G:
            case AT56G_SERDES_6P144G  :
            case AT56G_SERDES_6P25G   :
            case AT56G_SERDES_7P3728G :
            case AT56G_SERDES_7P5G    :
            case AT56G_SERDES_8P11008G:
            case AT56G_SERDES_8P5G    :
            case AT56G_SERDES_9P8304G :
            case AT56G_SERDES_10G     :
            case AT56G_SERDES_10P137G :
            case AT56G_SERDES_10P5187G:
            case AT56G_SERDES_12P1651G:
            case AT56G_SERDES_12P1875G:
            case AT56G_SERDES_12P8906G:
            case AT56G_SERDES_14P025G :
            case AT56G_SERDES_14P7456G:
            case AT56G_SERDES_15G     :
            case AT56G_SERDES_16P2201G:
            case AT56G_SERDES_20P625G :
            case AT56G_SERDES_24P3302G:
            case AT56G_SERDES_275G    :
            case AT56G_SERDES_28P05G  :
            case AT56G_SERDES_32G     :
            case AT56G_SERDES_46P25G  :
            case AT56G_SERDES_56G     :
            case AT56G_SERDES_56P1G   :
            case AT56G_SERDES_64G     :
            case AT56G_SERDES_3P072G  :
            case AT56G_SERDES_12P288G :
            case AT56G_SERDES_19P6608G:
            case AT56G_SERDES_MAX_G   :
            default:
                serdes_speed = SERDES_SPEED_0G;
                break;
        }
    }
    else
    {
        switch(txrx_speed)
        {
            case AT112G_SERDES_1P25G    :
                serdes_speed = SERDES_SPEED_1_25G;
                break;
            case AT112G_SERDES_3P125G   :
                serdes_speed = SERDES_SPEED_3_125G;
                break;
            case AT112G_SERDES_10P3125G :
                serdes_speed = SERDES_SPEED_10_3125G;
                break;
            case AT112G_SERDES_12P5G    :
                serdes_speed = SERDES_SPEED_12_5G;
                break;
            case AT112G_SERDES_25P78125G:
                serdes_speed = SERDES_SPEED_25_78125G;
                break;
            case AT112G_SERDES_26P5625G :
                serdes_speed = SERDES_SPEED_26_5625G;
                break;
            case AT112G_SERDES_28P125G  :
                serdes_speed = SERDES_SPEED_28_125G;
                break;
            case AT112G_SERDES_51P5625G :
                serdes_speed = SERDES_SPEED_51_5625G;
                break;
            case AT112G_SERDES_53P125G  :
                serdes_speed = SERDES_SPEED_53_125G;
                break;
            case AT112G_SERDES_56P25G   :
                serdes_speed = SERDES_SPEED_56_25G;
                break;
            case AT112G_SERDES_106GP25G :
                serdes_speed = SERDES_SPEED_106_25G;
                break;
            case AT112G_SERDES_112P5G   :
                serdes_speed = SERDES_SPEED_112_5G;
                break;
            case AT112G_SERDES_1P0625G  :
            case AT112G_SERDES_1P2288G  :
            case AT112G_SERDES_2P125G   :
            case AT112G_SERDES_2P4576G  :
            case AT112G_SERDES_2P5G     :
            case AT112G_SERDES_2P578125G:
            case AT112G_SERDES_4P25G    :
            case AT112G_SERDES_4P9152G  :
            case AT112G_SERDES_5G       :
            case AT112G_SERDES_5P15625G :
            case AT112G_SERDES_6P144G   :
            case AT112G_SERDES_6P25G    :
            case AT112G_SERDES_7P5G     :
            case AT112G_SERDES_8P5G     :
            case AT112G_SERDES_9P8304G  :
            case AT112G_SERDES_10P137G  :
            case AT112G_SERDES_10P51875G:
            case AT112G_SERDES_12P16512G:
            case AT112G_SERDES_12P1875G :
            case AT112G_SERDES_12P8906G :
            case AT112G_SERDES_14P025G  :
            case AT112G_SERDES_15G      :
            case AT112G_SERDES_20P625G  :
            case AT112G_SERDES_24P33024G:
            case AT112G_SERDES_27P1875G :
            case AT112G_SERDES_27P5G    :
            case AT112G_SERDES_28P05G   :
            case AT112G_SERDES_32P5G    :
            case AT112G_SERDES_46P25G   :
            case AT112G_SERDES_50G      :
            case AT112G_SERDES_56G      :
            case AT112G_SERDES_56P1G    :
            case AT112G_SERDES_112G     :
            case AT112G_SERDES_MAX_G    :
            default:
                serdes_speed = SERDES_SPEED_0G;
                break;
        }
    }
    return serdes_speed;
}

uint32 _sys_at_serdes_get_related_txrx_speed(uint8 serdes_speed, uint8 type)
{
    uint32 txrx_speed = 0;
    switch(serdes_speed)
    {
        case SERDES_SPEED_1_25G    :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_1P25G : AT112G_SERDES_1P25G;
            break;
        case SERDES_SPEED_3_125G   :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_3P125G : AT112G_SERDES_3P125G;
            break;
        case SERDES_SPEED_10_3125G :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_10P3125G : AT112G_SERDES_10P3125G;
            break;
        case SERDES_SPEED_11_40625G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_11P40625G : AT112G_SERDES_11P40625G;
            break;
        case SERDES_SPEED_12_5G    :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_12P5G : AT112G_SERDES_12P5G;
            break;
        case SERDES_SPEED_12_96875G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_12P96875G : AT112G_SERDES_12P96875G;
            break;
        case SERDES_SPEED_10_9375G :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_10P9375G : AT112G_SERDES_10P9375G;
            break;
        case SERDES_SPEED_20_625G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_20P625G : AT112G_SERDES_20P625G;
            break;
        case SERDES_SPEED_25_78125G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_25P7812G : AT112G_SERDES_25P78125G;
            break;
        case SERDES_SPEED_28_125G  :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_28P125G : AT112G_SERDES_28P125G;
            break;
        case SERDES_SPEED_26_5625G :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_26P5625G : AT112G_SERDES_26P5625G;
            break;
        case SERDES_SPEED_27_34375G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_27P34375G : AT112G_SERDES_27P34375G;
            break;
        case SERDES_SPEED_27_78125G:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_27P78125G : AT112G_SERDES_27P78125G;
            break;
        case SERDES_SPEED_37_5G    :
            ///TODO: not available
            break;
        case SERDES_SPEED_39_0625G :
            ///TODO: not available
            break;
        case SERDES_SPEED_51_5625G :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_51P5625G : AT112G_SERDES_51P5625G;
            break;
        case SERDES_SPEED_53_125G  :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_53P125G : AT112G_SERDES_53P125G;
            break;
        case SERDES_SPEED_56_25G   :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_56P25G : AT112G_SERDES_56P25G;
            break;
        case SERDES_SPEED_103_125G :
            ///TODO: not available
            break;
        case SERDES_SPEED_106_25G  :
            txrx_speed = AT112G_SERDES_106GP25G;
            break;
        case SERDES_SPEED_112_5G   :
            txrx_speed = AT112G_SERDES_112P5G;
            break;
        case SERDES_SPEED_42_5G   :
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_MAX_G : AT112G_SERDES_42P5G;
            break;
        case SERDES_SPEED_0G       :
        default:
            txrx_speed = (SYS_AT_SERDES_56G == type) ? AT56G_SERDES_MAX_G : AT112G_SERDES_MAX_G;
            break;
    }
    return txrx_speed;
}

int32
_sys_at_serdes_set_lane_swap(uint8 lchip, void* p_data)
{
    uint8   core_id     = 0;
    //uint8   power_up    = 0;
    uint8   lsd_lane    = 0;
    uint8   lane_in_hs  = 0;
    uint8   psd_flag    = 0;
    uint8   psd0_flag   = 0;
    uint8   dport_num   = 0;
    uint8   chip_type   = SYS_AT_GET_CHIP_TYPE(lchip);
    uint8   rlmhs_id    = 0;
    uint8   rlmhs_flag[AT_HSS_NUM_PER_MCMAC] = {0};
    uint16  serdes_base = 0;
    uint16  serdes_end  = 0;
    uint16  chan_id     = 0;
    uint16  chan_idx    = 0;
    uint16  dport       = 0;
    uint16  lsd_sc      = 0;
    uint16  lsd         = 0;
    uint16  psd         = 0;
    uint16  mac_id      = 0;
    uint16  pcs_id      = 0;
    uint16  psd0        = 0;
    uint16* p_map       = NULL;
    uint16  dport_list[AT_SERDES_NUM_PER_MCMAC] = {0};
    uint16  lsd_to_psd0[AT_HSS_NUM_PER_MCMAC][AT_SERDES_NUM_PER_HSS] = {{0}};
    uint32 support_speed               = 0;
    ctc_chip_serdes_info_t serdes_info = {0};
    sys_dmps_db_upt_info_t port_info   = {0};
    const sys_at_dmps_id_dictionary_t* p_dictionary = NULL;

    CTC_PTR_VALID_CHECK(p_data);
    p_map = (uint16*) ((ctc_chip_serdes_map_cfg_t*)p_data)->serdes_id;

    CTC_ERROR_RETURN(sys_at_datapath_dic_by_chip_type(lchip, &p_dictionary));
    if (NULL == p_dictionary)
    {
        return CTC_E_INVALID_CONFIG;
    }

    /* 1. para check */
    /* 1.1 check whether there is valid serdes id */
    for(lsd_lane = 0; lsd_lane < AT_SERDES_NUM_PER_MCMAC; lsd_lane++)
    {
        SYS_CONDITION_BREAK(DMPS_INVALID_VALUE_U16 != p_map[lsd_lane]);
    }
    if(CTC_HSS_SERDES_NUM <= lsd_lane)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% No valid serdes id!\n");
        return CTC_E_INVALID_PARAM;
    }

    /* 1.2 check whether serdes supports lane swap */
    if(SYS_AT_NW_SERDES_NUM <= p_map[lsd_lane])
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% This serdes do not support swap!\n");
        return CTC_E_INVALID_PARAM;
    }

    serdes_base = (p_map[lsd_lane] / AT_SERDES_NUM_PER_MCMAC) * AT_SERDES_NUM_PER_MCMAC;
    serdes_end  = serdes_base + AT_SERDES_NUM_PER_MCMAC;

    for(lsd_lane = 0; lsd_lane < AT_SERDES_NUM_PER_MCMAC; lsd_lane++)
    {
        /* 1.3 check serdes range */
        if(((serdes_base > p_map[lsd_lane]) || (serdes_end <= p_map[lsd_lane])) && 
           (DMPS_INVALID_VALUE_U16 != p_map[lsd_lane]))
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% This serdes id exceeds current hss!\n");
            return CTC_E_INVALID_PARAM;
        }

        /* 1.4 check validity of original psd */
        lsd  = serdes_base + lsd_lane;
        psd0 = DMPS_INVALID_VALUE_U16;
        (void) sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd, DMPS_DB_TYPE_PSD, NULL, &psd0);
        if (DMPS_INVALID_VALUE_U16 != psd0)
        {
            if (psd0_flag & (1 << (psd0 % AT_SERDES_NUM_PER_MCMAC)))
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% This serdes id duplicates!\n");
                return CTC_E_INVALID_PARAM;
            }
            else
            {
                psd0_flag |= (1 << (psd0 % AT_SERDES_NUM_PER_MCMAC));
            }
        }
        lsd_to_psd0[lsd_lane / AT_SERDES_NUM_PER_HSS][lsd_lane % AT_SERDES_NUM_PER_HSS] = psd0;

        /* 1.5 check whether psd is duplicate */
        if (DMPS_INVALID_VALUE_U16 != p_map[lsd_lane])
        {
            if (psd_flag & (1 << (p_map[lsd_lane] % AT_SERDES_NUM_PER_MCMAC)))
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% This serdes id duplicates!\n");
                return CTC_E_INVALID_PARAM;
            }
            else
            {
                psd_flag |= (1 << (p_map[lsd_lane] % AT_SERDES_NUM_PER_MCMAC));
            }
        }
    }

    /* 1.6 check wether psd is the same */
    if (psd_flag != psd0_flag)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Cannot change serdes when do lane swap!\n");
        return CTC_E_INVALID_PARAM;
    }

    /* 1.7 check whether the four serdes in a RlmHs should do lane swap */
    for (rlmhs_id = 0; rlmhs_id < AT_HSS_NUM_PER_MCMAC; rlmhs_id++)
    {
        for (lane_in_hs = 0; lane_in_hs < AT_SERDES_NUM_PER_HSS; lane_in_hs++)
        {
            if (lsd_to_psd0[rlmhs_id][lane_in_hs] != p_map[lane_in_hs + rlmhs_id * AT_SERDES_NUM_PER_HSS])
            {
                rlmhs_flag[rlmhs_id] = 1;
                break;
            }
        }
    }

    if ((!rlmhs_flag[0]) && (!rlmhs_flag[1]))
    {
        return CTC_E_NONE;
    }

    /* 2. switch serdes to none */
    serdes_info.serdes_mode        = CTC_CHIP_SERDES_NONE_MODE;
    serdes_info.overclocking_speed = CTC_CHIP_SERDES_OCS_MODE_NONE;
    for (rlmhs_id = 0; rlmhs_id < AT_HSS_NUM_PER_MCMAC; rlmhs_id++)
    {
        if (!rlmhs_flag[rlmhs_id])
        {
            continue;
        }

        for (lane_in_hs = 0; lane_in_hs < AT_SERDES_NUM_PER_HSS; lane_in_hs++)
        {
            if ((DMPS_INVALID_VALUE_U16 == lsd_to_psd0[rlmhs_id][lane_in_hs])
                 || (lsd_to_psd0[rlmhs_id][lane_in_hs]  == p_map[lane_in_hs + rlmhs_id * AT_SERDES_NUM_PER_HSS]))
            {
                continue;
            }

            serdes_info.serdes_id = lsd_to_psd0[rlmhs_id][lane_in_hs];
            CTC_ERROR_RETURN(_sys_usw_port_api_set_serdes_mode(lchip, &serdes_info));
        }
    }

    /* 3. change database */
    serdes_base = rlmhs_flag[0] ? serdes_base : (serdes_base + AT_SERDES_NUM_PER_HSS);
    serdes_end  = rlmhs_flag[1] ? serdes_end  : (serdes_end  - AT_SERDES_NUM_PER_HSS);
    /* 3.1 clear map and property */
    for (lsd = serdes_base; lsd < serdes_end; lsd++)
    {
        rlmhs_id = (lsd % AT_SERDES_NUM_PER_MCMAC)/AT_SERDES_NUM_PER_HSS;
        lane_in_hs = lsd % AT_SERDES_NUM_PER_HSS;
        SYS_CONDITION_CONTINUE(lsd_to_psd0[rlmhs_id][lane_in_hs] == p_map[lsd % AT_SERDES_NUM_PER_MCMAC]);

        if (sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_LSD, lsd))
        {
            CTC_ERROR_RETURN(_sys_at_datapath_get_port_chan_by_serdes(lchip, lsd, &chan_id, &dport));
            if ((DMPS_INVALID_VALUE_U16 == chan_id) || (DMPS_INVALID_VALUE_U16 == dport))
            {
                return CTC_E_INVALID_PARAM;
            }
            dport_list[dport_num] = dport;
            dport_num++;
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,            dport);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,          chan_id);
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IS_RSV, FALSE);
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_IS_RSV, FALSE);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));
            CTC_ERROR_RETURN(sys_usw_dmps_db_free_chan(lchip, chan_id));
            CTC_ERROR_RETURN(sys_usw_dmps_db_free_port(lchip, dport));
            core_id  = chan_id / AT_NW_CHAN_NUM_PER_CORE;
            chan_idx = chan_id % AT_NW_CHAN_NUM_PER_CORE;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_chan2lsd(lchip, core_id, chan_idx, 
                SYS_DP_CHAN_LPORT_OCCUPY_RSV, DMPS_INVALID_VALUE_U16, DMPS_INVALID_VALUE_U16));

            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,      lsd);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_SET_MAP_UPDATE(port_info);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_DPORT,         port_info.dport);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_CHAN_ID,       port_info.chan_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_MAC_ID,        port_info.mac_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_PCS_ID,        port_info.pcs_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_LOGIC_SERDES,  port_info.logic_serdes);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_OLD_PHYSIC_SERDES, port_info.physic_serdes);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,             DMPS_INVALID_VALUE_U16);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,           DMPS_INVALID_VALUE_U16);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID,            DMPS_INVALID_VALUE_U16);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PCS_ID,            DMPS_INVALID_VALUE_U16);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,      DMPS_INVALID_VALUE_U16);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES,     DMPS_INVALID_VALUE_U16);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));
        }
    }

    //power_up = _sys_at_mac_is_power_up(lchip, core_id, (serdes_base / AT_SERDES_NUM_PER_MCMAC) % AT_MCMAC_NUM_PER_CORE, TRUE);

    /* 3.2 Add new map and property */
    dport_num = 0;
    for (lsd = serdes_base; lsd < serdes_end; lsd++)
    {
        if (DMPS_INVALID_VALUE_U16 == p_map[lsd % AT_SERDES_NUM_PER_MCMAC])
        {
            continue;
        }

        rlmhs_id = (lsd % AT_SERDES_NUM_PER_MCMAC)/AT_SERDES_NUM_PER_HSS;
        lane_in_hs = lsd % AT_SERDES_NUM_PER_HSS;
        SYS_CONDITION_CONTINUE(lsd_to_psd0[rlmhs_id][lane_in_hs] == p_map[lsd % AT_SERDES_NUM_PER_MCMAC]);

        core_id  = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(lsd);
        lsd_sc   = lsd % DMPS_MAX_SERDES_NUM_PER_CORE;
        chan_idx = p_dictionary[lsd_sc].pp_id * SYS_AT_NW_CHAN_NUM_PER_PP +
                    (p_dictionary[lsd_sc].dp_id % SYS_AT_DP_NUM_PER_PP) * SYS_AT_NW_CHAN_NUM_PER_DP +
                    p_dictionary[lsd_sc].sub_chan;
        chan_id  = core_id * AT_NW_CHAN_NUM_PER_CORE + chan_idx;
        dport    = dport_list[dport_num];
        dport_num++;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_chan2lsd(lchip, core_id, chan_idx, SYS_DP_CHAN_LPORT_OCCUPY_IN_USE, lsd_sc, dport));
        /* opf: Assign channel and port */
        CTC_ERROR_RETURN(sys_usw_dmps_db_assign_chan(lchip, chan_id));
        CTC_ERROR_RETURN(sys_usw_dmps_db_assign_port(lchip, dport));

        /* set dport and chan property */
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                   dport);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,                 chan_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IS_RSV,        TRUE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_IS_RSV,        TRUE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_CORE_ID,       core_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_PP_ID,         p_dictionary[lsd_sc].pp_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,         p_dictionary[lsd_sc].dp_id % AT_DP_NUM_PER_PP);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,       p_dictionary[lsd_sc].txqm_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, p_dictionary[lsd_sc].mac_client % SYS_AT_NW_MAC_CLIENT_PER_DP);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID,   p_dictionary[lsd_sc].sub_chan);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_PRIO,          FALSE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

        /* set mac, pcs, lsd and psd property */
        psd    = p_map[lsd % AT_SERDES_NUM_PER_MCMAC];
        mac_id = lsd;
        pcs_id = lsd;
        support_speed  = _sys_at_datapath_get_serdes_support_speed_bmp(lchip, chip_type, lsd);
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_UPDATE(port_info);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID,        mac_id);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        pcs_id);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,  lsd);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, psd);
        /* MAC DB */
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,       FALSE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_SPEED,    0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_GROUP_ID, ((mac_id / AT_SERDES_NUM_PER_MCMAC) % AT_MCMAC_NUM_PER_CORE));
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_IDX,      SYS_AT_GET_MAC_IDX_BY_ID(mac_id));
        /* PCS DB */
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PCS_IDX, SYS_AT_GET_MAC_IDX_BY_ID(mac_id));
        /* LSD DB */
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_LANE_ID,  lsd % AT_SERDES_NUM_PER_MCMAC);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_PCSL_IDX, 0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_HSS_ID,   SYS_AT_MAP_SERDES_TO_HSS_IDX(lsd));
        /* PSD DB */
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_PLL_SEL,       0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_RATE_DIV,      0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_BIT_WIDTH,     0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_OCS,           CTC_CHIP_SERDES_OCS_MODE_NONE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_LANE_ID,       psd % AT_SERDES_NUM_PER_MCMAC);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SUPPORT_SPEED, support_speed);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SPEED,         0);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

        /* 4 config register */
        /*if (power_up)
        {
            CTC_ERROR_RETURN(_sys_at_mac_set_nw_config_by_mac_id(lchip, mac_id));
        }*/
        CTC_ERROR_RETURN(_sys_at_mac_set_nw_config_by_mac_id(lchip, mac_id));
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_prbs_tx_enable(sys_at_serdes_dev_t* p_dev, uint8 pattern)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        /*1. Select a loopback test pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_PAT_SEL), 
            SYS_AT_SERDES_REG_LANE, pattern));

        /*2. Program PT_TX_PHYREADY_FORCE_LANE = 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*3. Program PT_TX_EN_MODE_LANE[1:0] = 0x2*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, 2));

        /*4. Assert PT_TX_EN_LANE = 0x1 to start loopback test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN), 
            SYS_AT_SERDES_REG_LANE, 1));

        /*5. Toggle PT_TX_RST_LANE: 0x0 -> 0x1 -> 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*6. Restart Tx data by setting PT_TX_PHYREADY_FORCE_LANE = 0x1*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 1));
    }
    else
    {
        /*1. Select a loopback test pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_PATTERN_SEL), 
            SYS_AT_SERDES_REG_LANE, pattern));

        /*2. Program PT_TX_PHYREADY_FORCE_LANE = 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*3. Program PT_TX_EN_MODE_LANE[1:0] = 0x2*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, 2));

        /*4. Assert PT_TX_EN_LANE = 0x1 to start loopback test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_EN), 
            SYS_AT_SERDES_REG_LANE, 1));

        /*5. Toggle PT_TX_RST_LANE: 0x0 -> 0x1 -> 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*6. Restart Tx data by setting PT_TX_PHYREADY_FORCE_LANE = 0x1*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 1));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_prbs_tx_disable(sys_at_serdes_dev_t* p_dev)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        /*De-assert PT_TX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*De-assert PT_TX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        /*De-assert PT_TX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_EN), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*De-assert PT_TX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_prbs_rx_cnt_rst(sys_at_serdes_dev_t* p_dev)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(1000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(1000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(1000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(1000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_CNT_RST), SYS_AT_SERDES_REG_LANE, 0));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_prbs_rx_enable(sys_at_serdes_dev_t* p_dev, uint8 pattern)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        /*1. Select a loopback test pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_PAT_SEL), 
            SYS_AT_SERDES_REG_LANE, pattern));

        /*2. Program PT_RX_PHYREADY_FORCE_LANE = 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*3. Program PT_RX_EN_MODE_LANE[1:0] = 0x2*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, 2));

        /*4. Assert PT_RX_EN_LANE = 0x1 to start loopback test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_EN), 
            SYS_AT_SERDES_REG_LANE, 1));

        /*5. Toggle PT_RX_RST_LANE: 0x0 -> 0x1 -> 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*6. Restart Rx data by setting PT_TX_PHYREADY_FORCE_LANE = 0x1*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 1));
    }
    else
    {
        /*1. Select a loopback test pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_PATTERN_SEL), 
            SYS_AT_SERDES_REG_LANE, pattern));

        /*2. Program PT_RX_PHYREADY_FORCE_LANE = 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*3. Program PT_RX_EN_MODE_LANE[1:0] = 0x2*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, 2));

        /*4. Assert PT_RX_EN_LANE = 0x1 to start loopback test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_EN), 
            SYS_AT_SERDES_REG_LANE, 1));

        /*5. Toggle PT_RX_RST_LANE: 0x0 -> 0x1 -> 0x0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_RST), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*6. Restart Rx data by setting PT_RX_PHYREADY_FORCE_LANE = 0x1*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 1));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_prbs_rx_enable(sys_at_serdes_dev_t* p_dev, uint32* p_en)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_EN), SYS_AT_SERDES_REG_LANE, p_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_EN), SYS_AT_SERDES_REG_LANE, p_en));
    }
    return CTC_E_NONE;
}

/*Check PT_RX_LOCK_LANE to check the lock status.*/
/*Check PT_RX_PASS_LANE to check the PHY test result.*/
/*If both are 0x1, the test passes; otherwise, the test fails.*/
/*To check results, the error counts and data counts can be read through PT_RX_ERR_CNT_LANE[31:0] and*/
/*PT_RX_CNT_LANE[47:0] after PT_RX_CNT_READY_LANE = 0x1 or set PT_RX_CNT_PAUSE_LANE = 0x1*/
/*when PT_RX_CNT_READY_LANE = 0x0 to avoid reading counter transition data, which means that the Bit Error*/
/*Rates (BER) over the measurement time frame can be derived by these registers.*/
int32
_sys_at_serdes_set_prbs_rx_disable(sys_at_serdes_dev_t* p_dev)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        /*De-assert PT_RX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_EN), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*De-assert PT_RX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        /*De-assert PT_RX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_EN), 
            SYS_AT_SERDES_REG_LANE, 0));

        /*De-assert PT_RX_EN_LANE = 0x0 to stop PHY test*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_PHYREADY), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_prbs_tx(sys_at_serdes_dev_t* p_dev, uint8* p_en, uint8* p_pattern)
{
    uint32 pattern = 0;
    uint32 enable  = 0;

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TX_PAT_SEL), 
            SYS_AT_SERDES_REG_LANE, &pattern));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, &enable));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_TX_PATTERN_SEL), 
            SYS_AT_SERDES_REG_LANE, &pattern));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_TX_EN_MODE), 
            SYS_AT_SERDES_REG_LANE, &enable));
    }

    SYS_USW_VALID_PTR_WRITE(p_en, ((enable == 2) ? TRUE : FALSE));
    SYS_USW_VALID_PTR_WRITE(p_pattern, ((uint8)pattern));

    return CTC_E_NONE;
}

int32 _sys_at_speed_gbps_to_mbps(sys_at_serdes_dev_t* p_dev, uint32 speed, uint32* mbps)
{
    *mbps = 0;

    if(SYS_AT_SERDES_112G == p_dev->type)
    {
        switch (speed)
        {
            case AT112G_SERDES_1P0625G:         /* 1.0625 Gbps */
                *mbps = 1062;
                break;
            case AT112G_SERDES_1P2288G:         /* 1.2288 Gbps */
                *mbps = 1228;
                break;
            case AT112G_SERDES_1P25G:           /* 1.25 Gbps */
                *mbps = 1250;
                break;
            case AT112G_SERDES_2P125G:          /* 2.125 Gbps */
                *mbps = 2125;
                break;
            case AT112G_SERDES_2P4576G:         /* 2.4576 Gbps */
                *mbps = 2457;
                break;
            case AT112G_SERDES_2P5G:            /* 2.5 Gbps */
                *mbps = 2500;
                break;
            case AT112G_SERDES_2P578125G:       /* 2.578125 Gbps */
                *mbps = 2578;
                break;
            case AT112G_SERDES_3P125G:          /* 3.125 Gbps */
                *mbps = 3125;
                break;
            case AT112G_SERDES_4P25G:           /* 4.25 Gbps */
                *mbps = 4250;
                break;
            case AT112G_SERDES_4P9152G:         /* 4.9152 Gbps */
                *mbps = 4915;
                break;
            case AT112G_SERDES_5G:              /* 5.0 Gbps */
                *mbps = 5000;
                break;
            case AT112G_SERDES_5P15625G:        /* 5.15625 Gbps */
                *mbps = 5156;
                break;
            case AT112G_SERDES_6P144G:          /* 6.144 Gbps */
                *mbps = 6144;
                break;
            case AT112G_SERDES_6P25G:           /* 6.25 Gbps */
                *mbps = 6250;
                break;
            case AT112G_SERDES_7P5G:            /* 7.5 Gbps */
                *mbps = 7500;
                break;
            case AT112G_SERDES_8P5G:            /* 8.5 Gbps */
                *mbps = 8500;
                break;
            case AT112G_SERDES_9P8304G:         /* 9.8304 Gbps */
                *mbps = 9830;
                break;
            case AT112G_SERDES_10P137G:         /* 10.137 Gbps */
                *mbps = 10137;
                break;
            case AT112G_SERDES_10P3125G:        /* 10.3125 Gbps */
                *mbps = 10312;
                break;
            case AT112G_SERDES_10P51875G:       /* 10.51875 Gbps */
                *mbps = 10518;
                break;
            case AT112G_SERDES_10P9375G:     /* 10.9375 Gbps */
                *mbps = 10937;
                break;
            case AT112G_SERDES_11P40625G:    /* 11.40625 Gbps */
                *mbps = 11406;
                break;
            case AT112G_SERDES_12P16512G:       /* 12.16512 Gbps */
                *mbps = 12165;
                break;
            case AT112G_SERDES_12P1875G:        /* 12.1875 Gbps */
                *mbps = 12187;
                break;
            case AT112G_SERDES_12P5G:           /* 12.5 Gbps */
                *mbps = 12500;
                break;
            case AT112G_SERDES_12P8906G:        /* 12.8906 Gbps */
                *mbps = 12890;
                break;
            case AT112G_SERDES_12P96875G:    /* 12.96875 Gbps */
                *mbps = 12968;
                break;
            case AT112G_SERDES_14P025G:         /* 14.025 Gbps */
                *mbps = 14025;
                break;
            case AT112G_SERDES_15G:             /* 15.0 Gbps */
                *mbps = 15000;
                break;
            case AT112G_SERDES_20P625G:         /* 20.625 Gbps */
                *mbps = 20625;
                break;
            case AT112G_SERDES_24P33024G:       /* 24.33024 Gbps */
                *mbps = 24330;
                break;
            case AT112G_SERDES_25P78125G:       /* 25.78125 Gbps */
                *mbps = 25781;
                break;
            case AT112G_SERDES_26P5625G:        /* 26.5625 Gbps */
                *mbps = 26562;
                break;
            case AT112G_SERDES_27P1875G:        /* 27.1875 Gbps */
                *mbps = 27187;
                break;
            case AT112G_SERDES_27P34375G:    /* 27.34375 Gbps */
                *mbps = 27343;
                break;
            case AT112G_SERDES_27P5G:           /* 27.5 Gbps */
                *mbps = 27500;
                break;
            case AT112G_SERDES_27P78125G:    /* 27.78125 Gbps */
                *mbps = 27781;
                break;
            case AT112G_SERDES_28P05G:          /* 28.05 Gbps */
                *mbps = 28050;
                break;
            case AT112G_SERDES_28P125G:         /* 28.125 Gbps */
                *mbps = 28125;
                break;
            case AT112G_SERDES_32P5G:           /* 32.5 Gbps */
                *mbps = 32500;
                break;
            case AT112G_SERDES_46P25G:          /* 46.25 Gbps */
                *mbps = 46250;
                break;
            case AT112G_SERDES_50G:             /* 50.0 Gbps */
                *mbps = 50000;
                break;
            case AT112G_SERDES_51P5625G:        /* 51.5625 Gbps */
                *mbps = 51562;
                break;
            case AT112G_SERDES_53P125G:         /* 53.125 Gbps */
                *mbps = 53125;
                break;
            case AT112G_SERDES_56G:             /* 56.0 Gbps */
                *mbps = 56000;
                break;
            case AT112G_SERDES_56P1G:           /* 56.1 Gbps */
                *mbps = 56100;
                break;
            case AT112G_SERDES_56P25G:          /* 56.25 Gbps */
                *mbps = 56250;
                break;
            case AT112G_SERDES_106GP25G:        /* 106.25 Gbps */
                *mbps = 106250;
                break;
            case AT112G_SERDES_112G:            /* 112.0 Gbps */
                *mbps = 112000;
                break;
            case AT112G_SERDES_112P5G:          /* 112.5 Gbps */
                *mbps = 112500;
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }  
    }
   else
   {
        switch (speed)
        {
            case AT56G_SERDES_1P0625G:        /* 1.0625 Gbps */
                *mbps = 1062;
                break;
            case AT56G_SERDES_1P2288G:        /* 1.2288 Gbps */
                *mbps = 1228;
                break;
            case AT56G_SERDES_1P25G:          /* 1.25 Gbps */
                *mbps = 1250;
                break;
            case AT56G_SERDES_2P02752G:       /* 2.02752 Gbps */
                *mbps = 2027;
                break;
            case AT56G_SERDES_2P125G:         /* 2.125 Gbps */
                *mbps = 2125;
                break;
            case AT56G_SERDES_2P4576G:        /* 2.4576 Gbps */
                *mbps = 2457;
                break;
            case AT56G_SERDES_2P5G:           /* 2.5 Gbps */
                *mbps = 2500;
                break;
            case AT56G_SERDES_2P57812G:       /* 2.578125 Gbps */
                *mbps = 2578;
                break;
            case AT56G_SERDES_3P072G:         /* 3.072 Gbps */
                *mbps = 3072;
                break;
            case AT56G_SERDES_3P125G:         /* 3.125 Gbps */
                *mbps = 3125;
                break;
            case AT56G_SERDES_4P08804G:       /* 4.08804 Gbps */
                *mbps = 4088;
                break;
            case AT56G_SERDES_4P25G:          /* 4.25 Gbps */
                *mbps = 4250;
                break;
            case AT56G_SERDES_4P9152G:        /* 4.9152 Gbps */
                *mbps = 4915;
                break;
            case AT56G_SERDES_5G:            /* 5.0 Gbps */
                *mbps = 5000;
                break;
            case AT56G_SERDES_5P15625G:       /* 5.15625 Gbps */
                *mbps = 5156;
                break;
            case AT56G_SERDES_6P144G:         /* 6.144 Gbps */
                *mbps = 6144;
                break;
            case AT56G_SERDES_6P25G:          /* 6.25 Gbps */
                *mbps = 6250;
                break;
            case AT56G_SERDES_7P3728G:        /* 7.3728 Gbps */
                *mbps = 7372;
                break;
            case AT56G_SERDES_7P5G:           /* 7.5 Gbps */
                *mbps = 7500;
                break;
            case AT56G_SERDES_8P11008G:       /* 8.11008 Gbps */
                *mbps = 8110;
                break;
            case AT56G_SERDES_8P5G:           /* 8.5 Gbps */
                *mbps = 8500;
                break;
            case AT56G_SERDES_9P8304G:        /* 9.8304 Gbps */
                *mbps = 9830;
                break;
            case AT56G_SERDES_10G:            /* 10.0 Gbps */
                *mbps = 10000;
                break;
            case AT56G_SERDES_10P137G:        /* 10.137 Gbps */
                *mbps = 10137;
                break;
            case AT56G_SERDES_10P3125G:       /* 10.3125 Gbps */
                *mbps = 10312;
                break;
            case AT56G_SERDES_10P5187G:       /* 10.51875 Gbps */
                *mbps = 10518;
                break;
            case AT56G_SERDES_12P1651G:       /* 12.16512 Gbps */
                *mbps = 12165;
                break;
            case AT56G_SERDES_12P1875G:       /* 12.1875 Gbps */
                *mbps = 12187;
                break;
            case AT56G_SERDES_12P288G:        /* 12.288 Gbps */
                *mbps = 12288;
                break;
            case AT56G_SERDES_12P5G:          /* 12.5 Gbps */
                *mbps = 12500;
                break;
            case AT56G_SERDES_12P8906G:       /* 12.8906 Gbps */
                *mbps = 12890;
                break;
            case AT56G_SERDES_14P025G:        /* 14.025 Gbps */
                *mbps = 14025;
                break;
            case AT56G_SERDES_14P7456G:       /* 14.7456 Gbps */
                *mbps = 14745;
                break;
            case AT56G_SERDES_15G:            /* 15.0 Gbps */
                *mbps = 15000;
                break;
            case AT56G_SERDES_16P2201G:       /* 16.22016 Gbps */
                *mbps = 16220;
                break;
            case AT56G_SERDES_19P6608G:       /* 19.6608 Gbps */
                *mbps = 19660;
                break;
            case AT56G_SERDES_20P625G:        /* 20.625 Gbps */
                *mbps = 20625;
                break;
            case AT56G_SERDES_24P3302G:       /* 24.33024 Gbps */
                *mbps = 24330;
                break;
            case AT56G_SERDES_25P7812G:       /* 25.78125 Gbps */
                *mbps = 25781;
                break;
            case AT56G_SERDES_26P5625G:       /* 26.5625 Gbps */
                *mbps = 26562;
                break;
            case AT56G_SERDES_275G:           /* 27.5 Gbps */
                *mbps = 27500;
                break;
            case AT56G_SERDES_28P05G:         /* 28.05 Gbps */
                *mbps = 28050;
                break;
            case AT56G_SERDES_28P125G:        /* 28.125 Gbps */
                *mbps = 28125;
                break;
            case AT56G_SERDES_32G:            /* 32.0 Gbps */
                *mbps = 32000;
                break;
            case AT56G_SERDES_46P25G:         /* 46.25 Gbps */
                *mbps = 46250;
                break;
            case AT56G_SERDES_51P5625G:       /* 51.5625 Gbps */
                *mbps = 51562;
                break;
            case AT56G_SERDES_53P125G:        /* 53.125 Gbps */
                *mbps = 53125;
                break;
            case AT56G_SERDES_56G:            /* 56.0 Gbps */
                *mbps = 56000;
                break;
            case AT56G_SERDES_56P1G:          /* 56.1 Gbps */
                *mbps = 56100;
                break;
            case AT56G_SERDES_56P25G:         /* 56.25 Gbps */
                *mbps = 56250;
                break;
            case AT56G_SERDES_64G:            /* 64.0 Gbps */
                *mbps = 64000;
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }
   }

   return CTC_E_NONE;
}

int32
_sys_at_serdes_get_prbs_rx(sys_at_serdes_dev_t* p_dev, uint8* p_pattern, uint8* p_pass, uint64* p_tot_cnt, uint64* p_err_cnt)
{
    uint64 total_cnt = 0;
    uint64 err_cnt   = 0;
    uint32 cnt       = 0;
    uint8  pass      = 0;
    uint32 rx_lock   = 0;
    uint32 rx_pass   = 0;
    uint32 pattern   = 0;
    uint16 txwidth   = 0;
    uint16 rxwidth   = 0;
    uint16 width     = 0;
    
    CTC_ERROR_RETURN(_sys_at_serdes_get_data_width(p_dev, &txwidth, &rxwidth));

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(rxwidth)
        {
            case AT56G_DATABUS_32BIT:
                width = 32;
                break;
            case AT56G_DATABUS_40BIT:
                width = 40;
                break;
            case AT56G_DATABUS_64BIT:
                width = 64;
                break;
            default:
                width = 1;
                break;
        }
        /*get pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_PAT_SEL), 
            SYS_AT_SERDES_REG_LANE, &pattern));
        
        /*get result*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_LOCK), 
            SYS_AT_SERDES_REG_LANE, &rx_lock));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_PASS), 
            SYS_AT_SERDES_REG_LANE, &rx_pass));
        if((1 == rx_lock) && (1 == rx_pass))
        {
            pass = TRUE;
        }
        /*get counter*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_ERR_3100), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        err_cnt |= cnt;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_ERR_4732), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        err_cnt |= ((uint64)cnt) << 32;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_CNT_3100), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        total_cnt |= cnt;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_CNT_4732), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        total_cnt |= ((uint64)cnt) << 32;
    }
    else
    {
        switch (rxwidth)
        {
            case AT112G_DATABUS_32BIT:
                width = 32;
                break;
            case AT112G_DATABUS_40BIT:
                width = 40;
                break;
            case AT112G_DATABUS_64BIT:
                width = 64;
                break;
            case AT112G_DATABUS_80BIT:
                width = 80;
                break;
            case AT112G_DATABUS_128BIT:
                width = 128;
                break;
            case AT112G_DATABUS_160BIT:
                width = 160;
                break;
            default:
                width = 1;
                break;
        }
        /*get pattern*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_PATTERN_SEL), 
            SYS_AT_SERDES_REG_LANE, &pattern));

        /*get result*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_LOCK), 
            SYS_AT_SERDES_REG_LANE, &rx_lock));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_PASS), 
            SYS_AT_SERDES_REG_LANE, &rx_pass));
        if((1 == rx_lock) && (1 == rx_pass))
        {
            pass = TRUE;
        }
        /*get counter*/
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_ERR_31_0), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        err_cnt |= cnt;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_ERR_47_32), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        err_cnt |= ((uint64)cnt) << 32;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_CNT_31_0), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        total_cnt |= cnt;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_CNT_47_32), 
            SYS_AT_SERDES_REG_LANE, &cnt));
        total_cnt |= ((uint64)cnt) << 32;
    }

    SYS_USW_VALID_PTR_WRITE(p_pattern, (uint32)pattern);
    SYS_USW_VALID_PTR_WRITE(p_pass,    pass);
    SYS_USW_VALID_PTR_WRITE(p_tot_cnt, total_cnt*width);
    SYS_USW_VALID_PTR_WRITE(p_err_cnt, err_cnt);
    
#ifdef UINT64_PRINT_FMT_LU
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "Statistics: pattern %u, lock %u, pass %u, total %lu, err %lu\n", 
        pattern, rx_lock, rx_pass, total_cnt*width, err_cnt);
#else
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "Statistics: pattern %u, lock %u, pass %u, total %ju, err %ju\n", 
        pattern, rx_lock, rx_pass, total_cnt*width, err_cnt);
#endif

    return CTC_E_NONE;
}

int32
_sys_at_serdes_prbs_type2pattern(uint8 polynome_type, uint8* p_pattern)
{
    switch(polynome_type)
    {
        case 0:
        case 1:
            *p_pattern = AT_SERDES_PAT_PRBS7;
            break;
        case 2:
        case 3:
        case 12:
        case 16:
            *p_pattern = AT_SERDES_PAT_PRBS15;
            break;
        case 4:
        case 5:
            *p_pattern = AT_SERDES_PAT_PRBS23;
            break;
        case 6:
        case 7:
        case 13:
        case 17:
            *p_pattern = AT_SERDES_PAT_PRBS31;
            break;
        case 8:
        case 10:
        case 14:
            *p_pattern = AT_SERDES_PAT_PRBS9;
            break;
        case 9:
        case 11:
        case 15:
            *p_pattern = AT_SERDES_PAT_PRBS13_0;
            break;
        default:
            return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_prbs_pattern2type(uint8 pattern, uint8* p_polynome_type)
{
    switch(pattern)
    {
        case AT_SERDES_PAT_PRBS7:
            *p_polynome_type = 0;
            break;
        case AT_SERDES_PAT_PRBS15:
            *p_polynome_type = 2;
            break;
        case AT_SERDES_PAT_PRBS23:
            *p_polynome_type = 4;
            break;
        case AT_SERDES_PAT_PRBS31:
            *p_polynome_type = 6;
            break;
        case AT_SERDES_PAT_PRBS9:
            *p_polynome_type = 8;
            break;
        case AT_SERDES_PAT_PRBS13_0:
            *p_polynome_type = 9;
            break;
        default:
            return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_tx_prbs(uint8 lchip, ctc_chip_serdes_prbs_t *p_prbs)
{
    uint8 pattern = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    if(1 == p_prbs->value)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_prbs_type2pattern(p_prbs->polynome_type, &pattern));
        CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_tx_enable(&dev, pattern));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_tx_disable(&dev));
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_tx_prbs(uint8 lchip, ctc_chip_serdes_prbs_t *p_prbs)
{
    uint8 en = 0;
    uint8 pattern = 0;
    uint8 polynome_type = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_get_prbs_tx(&dev, &en, &pattern));
    CTC_ERROR_RETURN(_sys_at_serdes_prbs_pattern2type(pattern, &polynome_type));
    p_prbs->polynome_type = polynome_type;
    p_prbs->value = en;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_rx_prbs(uint8 lchip, ctc_chip_serdes_prbs_t *p_prbs)
{
    uint8 pattern = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    if(1 == p_prbs->value)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_prbs_type2pattern(p_prbs->polynome_type, &pattern));
        CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_rx_enable(&dev, pattern));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_rx_disable(&dev));
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_rx_prbs(uint8 lchip, ctc_chip_serdes_prbs_t *p_prbs)
{
    uint8 pass = 0;
    uint8 pattern = 0;
    uint64 err_cnt = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_get_prbs_rx(&dev, &pattern, &pass, NULL, &err_cnt));
    /*if error exceeds u32, regard as 0xffffffff*/
    p_prbs->error_cnt = (err_cnt > SYS_DMPS_INVALID_U32) ? SYS_DMPS_INVALID_U32 : ((uint32)err_cnt);
    CTC_ERROR_RETURN(_sys_at_serdes_prbs_pattern2type(pattern, &(p_prbs->polynome_type)));

    return CTC_E_NONE;
}

/*useage:*/
/*#1 chip serdes xx prbs tx enable/disable mode yy     enable/disable prbs tx pattern*/
/*#2 chip serdes xx prbs rx mode yy                    start a new prbs rx test*/
/*#3 show chip serdes xx prbs tx                       show tx pattern*/
/*#4 show chip serdes xx prbs rx                       if prbs rx test is running, get error count and stop test;*/
/*                                                     else if test stopped, run a new 1s test and stop it.*/
int32
_sys_at_serdes_set_prbs(uint8 lchip, void* p_data)
{
    uint32 en = 0;
    uint32 co = 0;
    uint32 fa = 0;
    uint16 train_stat = 0;
    uint32 gap_ms = 100;
    uint32 times = 30;
    uint32 prbs_rx_en = 0;
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_prbs_t* p_prbs = (ctc_chip_serdes_prbs_t*)p_data;
    ctc_chip_serdes_cfg_t   tx_en  = {0};
    CTC_PTR_VALID_CHECK(p_prbs);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%u\n", p_prbs->serdes_id, p_prbs->mode);*/

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    switch(p_prbs->mode)
    {
        case 0: /* 0--Rx */
            /*1. judge duplicate enable rx statistic*/
            CTC_ERROR_RETURN(_sys_at_serdes_get_prbs_rx_enable(&dev, &prbs_rx_en));
            if(!prbs_rx_en)
            {
                /*1.1 enable statitsic*/
                p_prbs->value = 1;
                CTC_ERROR_RETURN(_sys_at_serdes_set_rx_prbs(lchip, p_prbs));
                /*1.2 wait previous tx || rx train done*/
                while(times--)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_rx_train_en(&dev, &en, &co, &fa));
                    SYS_CONDITION_BREAK((!en) || (en && co));
                    sal_task_sleep(gap_ms);
                }
                times = 30;
                while(times--)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_training_status(&dev, &train_stat));
                    SYS_CONDITION_BREAK(SYS_PORT_CL72_PROGRESS != train_stat);
                    sal_task_sleep(gap_ms);
                }
                /*1.3 reset statistic*/
                CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_rx_cnt_rst(&dev));
            }
            /*2. get current statistic*/
            CTC_ERROR_RETURN(_sys_at_serdes_get_rx_prbs(lchip, p_prbs));
            break;
        case 1: /* 1--Tx */
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_prbs(lchip, p_prbs));
            /*default enable serdes tx*/
            if(1 == p_prbs->value)
            {
                tx_en.serdes_id = p_prbs->serdes_id;
                tx_en.dir = CTC_EGRESS;
                CTC_ERROR_RETURN(_sys_at_serdes_get_trx_en(lchip, (void*)(&tx_en)));
                if(0 == tx_en.value)
                {
                    tx_en.value = 1;
                    CTC_ERROR_RETURN(_sys_at_serdes_set_trx_en(lchip, (void*)(&tx_en)));
                }
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

/*useage:*/
/*#1 chip serdes xx prbs tx enable/disable mode yy     enable/disable prbs tx pattern*/
/*#2 chip serdes xx prbs rx mode yy                    start a new prbs rx test*/
/*#3 show chip serdes xx prbs tx                       show tx pattern*/
/*#4 show chip serdes xx prbs rx                       if prbs rx test is running, get error count and stop test;*/
/*                                                     else if test stopped, run a new 1s test and stop it.*/
int32
_sys_at_serdes_get_prbs(uint8 lchip, void* p_data)
{
    uint32 en = 0;
    uint32 co = 0;
    uint32 fa = 0;
    uint16 train_stat = 0;
    uint32 gap_ms = 100;
    uint32 times = 30;
    uint32 prbs_rx_en = 0;
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_prbs_t* p_prbs = (ctc_chip_serdes_prbs_t*)p_data;
    CTC_PTR_VALID_CHECK(p_prbs);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%u\n", p_prbs->serdes_id, p_prbs->mode);*/

    _sys_at_get_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    switch(p_prbs->mode)
    {
        case 0: /* 0--Rx */
            /*1. judge duplicate enable rx statistic*/
            CTC_ERROR_RETURN(_sys_at_serdes_get_prbs_rx_enable(&dev, &prbs_rx_en));
            if(!prbs_rx_en)
            {
                /*1.1 enable statitsic*/
                p_prbs->value = 1;
                CTC_ERROR_RETURN(_sys_at_serdes_set_rx_prbs(lchip, p_prbs));
                /*1.2 wait previous tx || rx train done*/
                while(times--)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_rx_train_en(&dev, &en, &co, &fa));
                    SYS_CONDITION_BREAK((!en) || (en && co));
                    sal_task_sleep(gap_ms);
                }
                times = 30;
                while(times--)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_training_status(&dev, &train_stat));
                    SYS_CONDITION_BREAK(SYS_PORT_CL72_PROGRESS != train_stat);
                    sal_task_sleep(gap_ms);
                }
                /*1.3 reset statistic*/
                CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_rx_cnt_rst(&dev));
                /*1.4 wait 1s*/
                sal_task_sleep(1000);
            }
            /*2. get statistics*/
            CTC_ERROR_RETURN(_sys_at_serdes_get_rx_prbs(lchip, p_prbs));
            /*3. disable statitsic*/
            p_prbs->value = 0;
            CTC_ERROR_RETURN(_sys_at_serdes_set_rx_prbs(lchip, p_prbs));
            break;
        case 1: /* 1--Tx */
            CTC_ERROR_RETURN(_sys_at_serdes_get_tx_prbs(lchip, p_prbs));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_txeq_param(uint8 lchip, ctc_chip_serdes_ffe_t* p_ffe)
{
    uint8 ffe_idx = 0;
    uint32 sign_bmp = 0;
    uint32 val[CTC_CHIP_FFE_PARAM_NUM] = {0}; /*absolute value of p_ffe->coefficient*/
    int16 coeff[CTC_CHIP_FFE_PARAM_NUM];
    //uint16 value = 0;
    sys_at_serdes_dev_t dev = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    _sys_at_get_serdes_dev(lchip, p_ffe->serdes_id, &dev);
    if(SYS_AT_SERDES_56G == dev.type)
    {        
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C0), 
            SYS_AT_SERDES_REG_LANE, &val[0]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C1), 
            SYS_AT_SERDES_REG_LANE, &val[1]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C2), 
            SYS_AT_SERDES_REG_LANE, &val[2]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C3), 
            SYS_AT_SERDES_REG_LANE, &val[3]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C4), 
            SYS_AT_SERDES_REG_LANE, &val[4]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_ANA_TX_C5), 
            SYS_AT_SERDES_REG_LANE, &val[5]));

        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_TO_ANA_TX_FIR_POL), 
            SYS_AT_SERDES_REG_LANE, &sign_bmp));
        for(ffe_idx = 0; ffe_idx < CTC_CHIP_FFE_PARAM_NUM; ffe_idx++)
        {
            if(CTC_IS_BIT_SET(sign_bmp, ffe_idx))
            {
                coeff[ffe_idx] = (int16)(val[ffe_idx]);
            }
            else
            {
                coeff[ffe_idx] = (int16)(-1*val[ffe_idx]);
            }
        }
        sal_memcpy(p_ffe->coefficient, coeff, CTC_CHIP_FFE_PARAM_NUM*sizeof(uint16));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C0), 
            SYS_AT_SERDES_REG_LANE, &val[0]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C1), 
            SYS_AT_SERDES_REG_LANE, &val[1]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C2), 
            SYS_AT_SERDES_REG_LANE, &val[2]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C3), 
            SYS_AT_SERDES_REG_LANE, &val[3]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C4), 
            SYS_AT_SERDES_REG_LANE, &val[4]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_C5), 
            SYS_AT_SERDES_REG_LANE, &val[5]));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_ANA_TX_FIR_POL), 
            SYS_AT_SERDES_REG_LANE, &sign_bmp));

        for(ffe_idx = 0; ffe_idx < CTC_CHIP_FFE_PARAM_NUM; ffe_idx++)
        {
            /*sign[ffe_idx] = CTC_IS_BIT_SET(sign_bmp, ffe_idx) ? 1 : 0;
            _sys_at_serdes_get_ffe_complement_from_origin(sign[ffe_idx], val[ffe_idx], &value);
            p_ffe->coefficient[ffe_idx] = value;*/
            if(CTC_IS_BIT_SET(sign_bmp, ffe_idx))
            {
                coeff[ffe_idx] = (int16)(val[ffe_idx]);
            }
            else
            {
                coeff[ffe_idx] = (int16)(-1*val[ffe_idx]);
            }
        }
        sal_memcpy(p_ffe->coefficient, coeff, CTC_CHIP_FFE_PARAM_NUM*sizeof(uint16));
    }
    p_ffe->status = 1; /*AT ffe share same registers in userdefine / 3ap*/
    return CTC_E_NONE;
}

/*TX full swing: |pre3Cursor(C0)| + |pre2Cursor(C1)| + |preCursor(C2)| + |postCursor(C4)| + |naCursor(C5)| + |mainCursor(C3)| = 63*/
/*Ordinarilly the sum of all cursor should keep in full swing. To ensure this criterion, the C3 value is 63 minus other cursors.*/
/*But this API allows all kinds of C values temporily, including no full swing. The caller should ensure correction of values.*/
int32
_sys_at_serdes_set_txeq_param(uint8 lchip, ctc_chip_serdes_ffe_t* p_ffe)
{
    uint8 ffe_idx = 0;
    uint32 sign_bmp = 0;
    uint32 sign[CTC_CHIP_FFE_PARAM_NUM] = {0}; /*0~negative 1~positive*/
    uint32 val[CTC_CHIP_FFE_PARAM_NUM] = {0}; /*absolute value of p_ffe->coefficient*/
    int16  coeff_sign[CTC_CHIP_FFE_PARAM_NUM] = {0};
    sys_at_serdes_dev_t dev = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    _sys_at_get_serdes_dev(lchip, p_ffe->serdes_id, &dev);

    sal_memcpy(coeff_sign, p_ffe->coefficient, CTC_CHIP_FFE_PARAM_NUM * sizeof(uint16));

    for(ffe_idx = 0; ffe_idx < CTC_CHIP_FFE_PARAM_NUM; ffe_idx++)
    {
        if(coeff_sign[ffe_idx] >= 0)
        {
            sign[ffe_idx] = 1;
            val[ffe_idx] = (uint32)coeff_sign[ffe_idx];
        }
        else
        {
            sign[ffe_idx] = 0;
            val[ffe_idx] = (uint32)(-1*coeff_sign[ffe_idx]);
        }
    }
    if(SYS_AT_SERDES_56G == dev.type)
    {
        /*set sign*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_FIR_TAP_POL_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_TX_FIR_TAP_POL), 
            SYS_AT_SERDES_REG_LANE, &sign_bmp));
        for(ffe_idx = 0; ffe_idx < CTC_CHIP_FFE_PARAM_NUM; ffe_idx++)
        {
            sign_bmp = ((sign_bmp & ~(1 << ffe_idx)) | (sign[ffe_idx] << ffe_idx));
        }
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_FIR_TAP_POL), 
            SYS_AT_SERDES_REG_LANE, sign_bmp));

        /*set value*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C0_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C0), 
            SYS_AT_SERDES_REG_LANE, val[0]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C1_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C1), 
            SYS_AT_SERDES_REG_LANE, val[1]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C2_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C2), 
            SYS_AT_SERDES_REG_LANE, val[2]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C3_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C3), 
            SYS_AT_SERDES_REG_LANE, val[3]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C4_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C4), 
            SYS_AT_SERDES_REG_LANE, val[4]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C5_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_C5), 
            SYS_AT_SERDES_REG_LANE, val[5]));

        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_UP_FORCE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_UP), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_task_sleep(1);
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "delay 1\n");
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TX_UP), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        /*set sign*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_POL_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_POL), 
            SYS_AT_SERDES_REG_LANE, &sign_bmp));
        for(ffe_idx = 0; ffe_idx < CTC_CHIP_FFE_PARAM_NUM; ffe_idx++)
        {
            sign_bmp = ((sign_bmp & ~(1 << ffe_idx)) | (sign[ffe_idx] << ffe_idx));
        }
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_POL), 
            SYS_AT_SERDES_REG_LANE, sign_bmp));

        /*set value*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C0_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C0), 
            SYS_AT_SERDES_REG_LANE, val[0]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C1_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C1), 
            SYS_AT_SERDES_REG_LANE, val[1]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C2_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C2), 
            SYS_AT_SERDES_REG_LANE, val[2]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C3_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C3), 
            SYS_AT_SERDES_REG_LANE, val[3]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C4_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C4), 
            SYS_AT_SERDES_REG_LANE, val[4]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C5_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_C5), 
            SYS_AT_SERDES_REG_LANE, val[5]));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_UPDATE_F), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_UPDATE), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_task_sleep(1);
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "delay 1\n");
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TX_FIR_UPDATE), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_ffe(uint8 lchip, void* p_data)
{
    ctc_chip_serdes_ffe_t* p_ffe = (ctc_chip_serdes_ffe_t*)p_data;

    CTC_PTR_VALID_CHECK(p_ffe);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%d\n", p_ffe->serdes_id, p_ffe->mode);*/

    CTC_ERROR_RETURN(_sys_at_serdes_valid_check(lchip, p_ffe->serdes_id));

    switch(p_ffe->mode)
    {
        case CTC_CHIP_SERDES_FFE_MODE_TYPICAL:
            break;
        case CTC_CHIP_SERDES_FFE_MODE_DEFINE:
            CTC_ERROR_RETURN(_sys_at_serdes_set_txeq_param(lchip, p_ffe));
            break;
        case CTC_CHIP_SERDES_FFE_MODE_3AP:
        default:
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Mode 3AP not support!\n");
            return CTC_E_NOT_SUPPORT;
    }
    
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_ffe(uint8 lchip, void* p_data)
{
    ctc_chip_serdes_ffe_t* p_ffe = (ctc_chip_serdes_ffe_t*)p_data;

    CTC_PTR_VALID_CHECK(p_ffe);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%d\n", p_ffe->serdes_id, p_ffe->mode);*/

    CTC_ERROR_RETURN(_sys_at_serdes_valid_check(lchip, p_ffe->serdes_id));
    
    CTC_ERROR_RETURN(_sys_at_serdes_get_txeq_param(lchip, p_ffe));

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_rx_train_en(sys_at_serdes_dev_t* p_dev, uint16 en)
{
#ifdef EMULATION_ENV
#else
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN0, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN0, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN0, 0));
                    sal_udelay(1000);
                }
                break;
            case 1:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN1, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN1, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN1, 0));
                    sal_udelay(1000);
                }
                break;
            case 2:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN2, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN2, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN2, 0));
                    sal_udelay(1000);
                }
                break;
            case 3:
            default:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN3, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN3, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_TRAINEN3, 0));
                    sal_udelay(1000);
                }
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN0, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN0, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN0, 0));
                    sal_udelay(1000);
                }
                break;
            case 1:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN1, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN1, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN1, 0));
                    sal_udelay(1000);
                }
                break;
            case 2:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN2, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN2, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN2, 0));
                    sal_udelay(1000);
                }
                break;
            case 3:
            default:
                if(en) 
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN3, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN3, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_TRAIN_EN3, 0));
                    sal_udelay(1000);
                }
                break;
        }
    }
#endif
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_rx_train_en(sys_at_serdes_dev_t* p_dev, uint32* p_train_en, uint32* p_train_co, uint32* p_train_fa)
{
#ifdef EMULATION_ENV
    SYS_USW_VALID_PTR_WRITE(p_train_en, 1);
    /*SYS_USW_VALID_PTR_WRITE(p_train_co, 1);*/
    /*SYS_USW_VALID_PTR_WRITE(p_train_fa, 0);*/
    SYS_USW_VALID_PTR_WRITE(p_train_co, _sys_at_milli_rand(900));
    SYS_USW_VALID_PTR_WRITE(p_train_fa, _sys_at_milli_rand(2));
#else
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINEN0, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINCO0, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINFA0, p_train_fa));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINEN1, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINCO1, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINFA1, p_train_fa));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINEN2, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINCO2, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINFA2, p_train_fa));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINEN3, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINCO3, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_TRAINFA3, p_train_fa));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_EN0, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_CO0, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_FA0, p_train_fa));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_EN1, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_CO1, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_FA1, p_train_fa));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_EN2, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_CO2, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_FA2, p_train_fa));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_EN3, p_train_en));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_CO3, p_train_co));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_TRAIN_FA3, p_train_fa));
                break;
        }
    }
#endif
    return CTC_E_NONE;
}

/*ONLY support RX TRAIN AUTO*/
int32
_sys_at_serdes_set_ctle(uint8 lchip, void* p_data)
{
    uint32                  times     = 300;
    uint32                  en        = 0;
    uint32                  co        = 0;
    uint32                  fa        = 0;
    uint32                  sq_det    = 0;
    sys_at_serdes_dev_t     dev       = {0};
    ctc_chip_serdes_ctle_t* p_ctle    = (ctc_chip_serdes_ctle_t*)p_data;

    SYS_CONDITION_RETURN((NULL == p_ctle), CTC_E_INVALID_PTR);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, en:%u\n", p_ctle->serdes_id, p_ctle->auto_en);*/

    _sys_at_get_serdes_dev(lchip, p_ctle->serdes_id, &dev);

    if(p_ctle->auto_en) /*enable rx train*/
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_sq_det(&dev, &sq_det));
        if(1 == sq_det)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "RX train no signal, sq %u\n", sq_det);
            return CTC_E_NONE;
        }
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_train_en(&dev, p_ctle->auto_en));
        while(times--)
        {
            sal_task_sleep(10);
            CTC_ERROR_RETURN(_sys_at_serdes_get_rx_train_en(&dev, &en, &co, &fa));
            if(en && co)
            {
                if(fa)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "RX train fail\n");
                    return CTC_E_HW_FAIL;
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_train_en(&dev, 0));
                    return CTC_E_NONE;
                }
            }
        }
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "RX train timeout\n");
        return CTC_E_HW_TIME_OUT;
    }
    else /*disable rx train*/
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_train_en(&dev, p_ctle->auto_en));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_ctle(uint8 lchip, void* p_data)
{
    uint16                  serdes_id = DMPS_INVALID_VALUE_U16;
    sys_at_serdes_dev_t     dev       = {0};
    ctc_chip_serdes_ctle_t* p_ctle    = (ctc_chip_serdes_ctle_t*)p_data;
    uint32                  ctle_r  = 0;
    uint32                  ctle_c  = 0;
    uint32                  ctle_gc  = 0;

    SYS_CONDITION_RETURN((NULL == p_ctle), CTC_E_INVALID_PTR);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, en:%u\n", serdes_id, p_ctle->auto_en);*/

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    if(SYS_AT_SERDES_112G == dev.type)
    {
        (void) _sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TRAIN_CTLE_R), SYS_AT_SERDES_REG_LANE, &ctle_r);
        (void) _sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TRAIN_CTLE_C), SYS_AT_SERDES_REG_LANE, &ctle_c);
        (void) _sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TRAIN_CTLE_GC), SYS_AT_SERDES_REG_LANE, &ctle_gc);
        
        p_ctle->value[0] = (uint16)ctle_r;
        p_ctle->value[1] = (uint16)ctle_c;
        p_ctle->value[2] = (uint16)ctle_gc;
    }
    else
    {
        /*TODO : AT 56G */
    }
    
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_precode_en(uint8 lchip, uint16 serdes_id, uint8 dir, uint32 en)
{
    sys_at_serdes_dev_t dev = {0};
    uint8 lane = AT_SERDES_GET_LANE(serdes_id);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, dir:%u, en:%u\n", serdes_id, dir, en);*/

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_PRECODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_PRECODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_PRECODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_PRECODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_PRECODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_PRECODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_PRECODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_PRECODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    else
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_PRECODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_PRECODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_PRECODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_PRECODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_PRECODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_PRECODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_PRECODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_PRECODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }

    return CTC_E_NONE;
}


int32
_sys_at_serdes_get_precode_en(uint8 lchip, uint16 serdes_id, uint8 dir, uint32* p_en)
{
    sys_at_serdes_dev_t dev = {0};
    uint8 lane = AT_SERDES_GET_LANE(serdes_id);
    uint32 value = 0;

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, dir:%u\n", serdes_id, dir);*/

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_PRECODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_PRECODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_PRECODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_PRECODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_PRECODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_PRECODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_PRECODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_PRECODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    else
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_PRECODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_PRECODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_PRECODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_PRECODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_PRECODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_PRECODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_PRECODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_PRECODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    *p_en = value;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_graycode_en(uint8 lchip, uint16 serdes_id, uint8 dir, uint32 en)
{
    sys_at_serdes_dev_t dev = {0};
    uint8 lane = AT_SERDES_GET_LANE(serdes_id);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, dir:%u, en:%u\n", serdes_id, dir, en);*/

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    else
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN0, en));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN1, en));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN2, en));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN3, en));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_graycode_en(uint8 lchip, uint16 serdes_id, uint8 dir, uint32* p_en)
{
    sys_at_serdes_dev_t dev = {0};
    uint8 lane = AT_SERDES_GET_LANE(serdes_id);
    uint32 value = 0;

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, dir:%u\n", serdes_id, dir);*/

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_GRAYCODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_TX_GRAYCODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    else
    {
        if(DMPS_RX == dir)
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_GRAYCODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN0, &value));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN1, &value));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN2, &value));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_TX_GRAYCODE_EN3, &value));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
    }
    *p_en = value;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_precode(uint8 lchip, void* p_data)
{
    uint8  dir                       = 0;
    uint32 en                        = 0;
    uint32 en_prv                    = 0;
    ctc_chip_serdes_cfg_t* p_pre_coding = (ctc_chip_serdes_cfg_t*)p_data;

    CTC_PTR_VALID_CHECK(p_pre_coding);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, en:%u\n", p_pre_coding->serdes_id, p_pre_coding->value);*/

    dir = p_pre_coding->dir;
    en  = (uint32)p_pre_coding->value;

    CTC_ERROR_RETURN(_sys_at_serdes_get_precode_en(lchip, p_pre_coding->serdes_id, dir, &en_prv));
    SYS_CONDITION_RETURN(en == en_prv, CTC_E_NONE);
    CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, p_pre_coding->serdes_id, dir, en));
    
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_precode(uint8 lchip, void* p_data)
{
    uint8  dir                       = 0;
    uint32 en                        = 0;
    ctc_chip_serdes_cfg_t* p_pre_coding = (ctc_chip_serdes_cfg_t*)p_data;

    CTC_PTR_VALID_CHECK(p_pre_coding);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d\n", p_pre_coding->serdes_id);*/

    CTC_ERROR_RETURN(_sys_at_serdes_get_precode_en(lchip, p_pre_coding->serdes_id, dir, &en));

    p_pre_coding->value = (uint16)en;
    
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_pll_lock(uint8 lchip, void* p_data)
{
    uint16                      serdes_id = DMPS_INVALID_VALUE_U16;
    uint32                      lock_tx   = 0;
    uint32                      lock_rx   = 0;
    uint8                       core_id   = 0;
    uint8                       lock      = 0;
    uint8                       lane      = 0;
    sys_at_serdes_dev_t         dev       = {0};
    ctc_chip_pll_lock_status_t* p_pll     = (ctc_chip_pll_lock_status_t*)p_data;
    
    SYS_CONDITION_RETURN((NULL == p_pll), CTC_E_INVALID_PTR);
    serdes_id = p_pll->serdes_id;
    lane = AT_SERDES_GET_LANE(serdes_id);

    if(p_pll->type)
    {
        core_id = SYS_AT_GET_CORE_ID_BY_SERDES(serdes_id);
        lock = (CTC_E_NONE == _sys_at_datapath_check_core_pll_lock(lchip, core_id)) ? TRUE : FALSE;
    }
    else
    {
        _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
        
        if(SYS_AT_SERDES_56G == dev.type)
        {
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_RX0, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_TX0, &lock_tx));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_RX1, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_TX1, &lock_tx));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_RX2, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_TX2, &lock_tx));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_RX3, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_PLL_RDY_TX3, &lock_tx));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        else
        {
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_RX0, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_TX0, &lock_tx));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_RX1, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_TX1, &lock_tx));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_RX2, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_TX2, &lock_tx));
                    break;
                case 3:
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_RX3, &lock_rx));
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_PLL_RDY_TX3, &lock_tx));
                    break;
                default:
                    return CTC_E_HW_FAIL; /* Invalid lane */
            }
        }
        lock = (lock_tx && lock_rx) ? TRUE : FALSE;
    }
    p_pll->status = lock;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_force_ready(sys_at_serdes_dev_t* p_dev, uint32 is_force, uint32 rdy)
{
    uint8  lane = AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN0, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL0, rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN1, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL1, rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN2, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL2, rdy));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN3, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL3, rdy));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN0, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL0, rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN1, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL1, rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN2, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL2, rdy));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN3, is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL3, rdy));
                break;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_force_ready(sys_at_serdes_dev_t* p_dev, uint16* p_is_force, uint16* p_rdy)
{
#ifdef EMULATION_ENV
    SYS_USW_VALID_PTR_WRITE(p_is_force, 1);
    SYS_USW_VALID_PTR_WRITE(p_rdy, 1);
#else
    uint32 is_force  = 0;
    uint32 force_val = 0;
    uint8  lane      = AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN0, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL0, &force_val));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN1, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL1, &force_val));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN2, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL2, &force_val));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_EN3, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_FORCE_PMA_RDY_VAL3, &force_val));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN0, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL0, &force_val));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN1, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL1, &force_val));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN2, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL2, &force_val));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_EN3, &is_force));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_FORCE_PMA_RDY_VAL3, &force_val));
                break;
        }
    }

    SYS_USW_VALID_PTR_WRITE(p_is_force, is_force);
    SYS_USW_VALID_PTR_WRITE(p_rdy, force_val);
#endif
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_sq_thrd(sys_at_serdes_dev_t* p_dev, uint32* p_thrd)
{
    uint32 value;
    
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_SQ_RES_RD), 
            SYS_AT_SERDES_REG_LANE, &value));
        value -= 0x20;
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_SQ_RES_RD), 
            SYS_AT_SERDES_REG_LANE, &value));
        value -= 0x20;
    }
    SYS_USW_VALID_PTR_WRITE(p_thrd, value);
    return CTC_E_NONE;
}


int32
_sys_at_serdes_get_sq_det(sys_at_serdes_dev_t* p_dev, uint32* p_sq_det)
{
#ifdef EMULATION_ENV
    /**p_sq_det = 0;*/
    *p_sq_det = _sys_at_milli_rand(10);
#else
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_SQ_DET_LPF0, p_sq_det));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_SQ_DET_LPF1, p_sq_det));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_SQ_DET_LPF2, p_sq_det));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_SQ_DET_LPF3, p_sq_det));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_SQ_DET_LPF0, p_sq_det));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_SQ_DET_LPF1, p_sq_det));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_SQ_DET_LPF2, p_sq_det));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_SQ_DET_LPF3, p_sq_det));
                break;
        }
    }
#endif
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_signal_detect(uint8 lchip, uint16 psd, uint8* p_is_detect, uint8* p_raw_sigdet)
{
    uint32 sq_det = 0;
    uint16 is_fc  = 0;
    uint16 fc_val = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, psd, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_get_sq_det(&dev, &sq_det));

    CTC_ERROR_RETURN(_sys_at_serdes_get_force_ready(&dev, &is_fc, &fc_val));

    SYS_USW_VALID_PTR_WRITE(p_raw_sigdet, (1 == sq_det ? 0 : 1));
    SYS_USW_VALID_PTR_WRITE(p_is_detect, (uint8)(is_fc ? fc_val : (1 == sq_det ? 0 : 1)));

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_dtl_clamp(uint8 lchip, uint16 psd, uint32* p_dtl_clp)
{
    sys_at_serdes_dev_t dev = {0};
    _sys_at_get_serdes_dev(lchip, psd, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        switch(AT_SERDES_GET_LANE(dev.serdes_id))
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_DTL_CLAMP0, p_dtl_clp));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_DTL_CLAMP1, p_dtl_clp));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_DTL_CLAMP2, p_dtl_clp));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT56G_PIN_RX_DTL_CLAMP3, p_dtl_clp));
                break;
        }
    }
    else
    {
        switch(AT_SERDES_GET_LANE(dev.serdes_id))
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_DTL_CLAMP0, p_dtl_clp));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_DTL_CLAMP1, p_dtl_clp));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_DTL_CLAMP2, p_dtl_clp));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(&dev, AT112G_PIN_RX_DTL_CLAMP3, p_dtl_clp));
                break;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_cdr_lock(uint8 lchip, uint16 psd, uint32* p_lock)
{
    uint32 lock = 0;
    sys_at_serdes_dev_t dev = {0};
    
    _sys_at_get_serdes_dev(lchip, psd, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        ///TODO: IP56 has no cdr lock status
        lock = 1;
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_RX_CDR_LOCK), 
            SYS_AT_SERDES_REG_LANE, &lock));
    }
    SYS_USW_VALID_PTR_WRITE(p_lock, lock);
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_pll_sel(sys_at_serdes_dev_t* p_dev, uint32* p_pll_sel)
{
    uint32 pll_sel = 0;

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_PLL_SEL_LANE), 
            SYS_AT_SERDES_REG_LANE, &pll_sel));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_PLL_SEL_LANE), 
            SYS_AT_SERDES_REG_LANE, &pll_sel));
    }
    SYS_USW_VALID_PTR_WRITE(p_pll_sel, pll_sel);
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_port_serdes_info(uint8 lchip, void* p_data)
{
    uint16 psd_s = 0;
    uint16 psd_d[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint8  psd_num = 0;
    uint16 lport = 0;
    uint16 drv_port = 0;
    uint8  gchip = 0;
    uint8  ocs = 0;
    uint32 rx_ready = 0;
    ctc_port_serdes_info_t* p_serdes_port = (ctc_port_serdes_info_t*)p_data;
    
    CTC_PTR_VALID_CHECK(p_serdes_port);
    psd_s = p_serdes_port->serdes_id;

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PSD, psd_s, 
        DMPS_DB_TYPE_PSD, &psd_num, psd_d));
    SYS_CONDITION_RETURN(psd_num > CTC_PORT_SERDES_MAX_NUM, CTC_E_INVALID_PARAM);
    p_serdes_port->serdes_num = psd_num;
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_lport_by_psd(lchip, psd_s, &lport));
    drv_port                          = lport;
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    p_serdes_port->gport              = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, drv_port);
    sal_memcpy(p_serdes_port->serdes_id_array, psd_d, psd_num * sizeof(uint16));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_ifmode(lchip, lport, &(p_serdes_port->serdes_mode)));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_serdes_ocs(lchip, lport, &ocs));
    p_serdes_port->overclocking_speed = ocs;
    CTC_ERROR_RETURN(_sys_at_serdes_get_signal_detect(lchip, psd_s, NULL, &(p_serdes_port->signal_detect)));
    CTC_ERROR_RETURN(_sys_at_serdes_get_cdr_lock(lchip, psd_s, &rx_ready));
    p_serdes_port->ready = rx_ready;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_polarity(uint8 lchip, uint16 serdes_id, uint8 dir, uint16 val)
{
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(DMPS_RX == dir) //rx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXD_INV), 
                SYS_AT_SERDES_REG_LANE, val));
        }
        else //tx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXD_INV), 
                SYS_AT_SERDES_REG_LANE, val));
        }
    }
    else
    {
        if(DMPS_RX == dir) //rx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXD_INV), 
                SYS_AT_SERDES_REG_LANE, val));
        }
        else //tx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXD_INV), 
                SYS_AT_SERDES_REG_LANE, val));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_polarity(uint8 lchip, uint16 serdes_id, uint8 dir, uint16 *p_val)
{
    uint32 value = 0;
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    if(SYS_AT_SERDES_56G == dev.type)
    {
        if(0 == dir) //rx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_RXD_INV), 
                SYS_AT_SERDES_REG_LANE, &value));
        }
        else //tx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_TXD_INV), 
                SYS_AT_SERDES_REG_LANE, &value));
        }
    }
    else
    {
        if(0 == dir) //rx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_RXD_INV), 
                SYS_AT_SERDES_REG_LANE, &value));
        }
        else //tx
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TXD_INV), 
                SYS_AT_SERDES_REG_LANE, &value));
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_val, (uint16)value);

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_serdes_polarity(uint8 lchip, void* p_data)
{
    uint16  serdes_id = 0;
    uint8   pol = 0;
    uint8   dir = 0;
    ctc_chip_serdes_polarity_t*   p_polarity = (ctc_chip_serdes_polarity_t*)p_data;

    CTC_PTR_VALID_CHECK(p_polarity);
    serdes_id = p_polarity->serdes_id;
    pol = (0 == p_polarity->polarity_mode) ? DMPS_POLARITY_NORM : DMPS_POLARITY_INV;
    dir = (0 == p_polarity->dir) ? DMPS_RX : DMPS_TX;
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, serdes_id, dir, pol));
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_psd_polarity(lchip, serdes_id, dir, pol));

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_serdes_polarity(uint8 lchip, void* p_data)
{
    uint16 serdes_id = 0;
    uint16 value     = 0;
    ctc_chip_serdes_polarity_t*   p_polarity = (ctc_chip_serdes_polarity_t*)p_data;

    CTC_PTR_VALID_CHECK(p_polarity);
    serdes_id = p_polarity->serdes_id;

    CTC_ERROR_RETURN(_sys_at_serdes_get_polarity(lchip, serdes_id, p_polarity->dir, &value));

    p_polarity->polarity_mode = value;

    return CTC_E_NONE;
}

void _sys_at_serdes_wait_ms(sys_at_serdes_dev_t* p_dev, uint32 ms)
{
    sal_task_sleep(ms);
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "delay %u\n", ms);
}

int32 
_sys_at_serdes_read_reg(sys_at_serdes_dev_t* p_dev, uint32 reg, uint32 *value)
{
#if (SDB_MEM_MODEL == SDB_MODE)
        return CTC_E_NONE;
#endif
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(AT_SERDES_SIM))
    uint32 core_id = SYS_AT_GET_CORE_ID_BY_SERDES(p_dev->serdes_id);
    uint32 grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    SYS_CONDITION_RETURN(core_id > 8, CTC_E_INVALID_PARAM);
    grp_id = (0x000000ff & grp_id) | (0x00400000 << core_id);

    CTC_ERROR_RETURN(drv_chip_read_hss(p_dev->lchip, grp_id, reg, (void*)value));
#endif
    return CTC_E_NONE;
}

int32 
_sys_at_serdes_write_reg(sys_at_serdes_dev_t* p_dev, uint32 reg, uint32 value)
{
#if (SDB_MEM_MODEL == SDB_MODE)
        return CTC_E_NONE;
#endif
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(AT_SERDES_SIM))
    uint32 core_id = SYS_AT_GET_CORE_ID_BY_SERDES(p_dev->serdes_id);
    uint32 grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    SYS_CONDITION_RETURN(core_id > 8, CTC_E_INVALID_PARAM);
    grp_id = (0x000000ff & grp_id) | (0x00400000 << core_id);
    CTC_ERROR_RETURN(drv_chip_write_hss(p_dev->lchip, grp_id, reg, (void*)(&value)));
#endif
    return CTC_E_NONE;
}

int32 _sys_at_serdes_read_reg_lane(sys_at_serdes_dev_t* p_dev, uint32 reg, 
                                                uint8 reg_type, uint32* p_data)
{
    _sys_at_serdes_field_t* p_lane_sel = NULL;
    uint32 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 reg_val = 0;
    /* Lane switching is necessary for register adresses from 0 ~ 0x7FFC */
    if((0x8000 > reg) && (SYS_AT_SERDES_REG_LANE == reg_type))
    {
        p_lane_sel = (SYS_AT_SERDES_56G == p_dev->type) ? 
            REG_STR(F_AT56G_LANE_SEL) : REG_STR(F_AT112G_LANE_SEL);
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg(p_dev, p_lane_sel->reg, &reg_val));
        if(lane != (reg_val & (~(p_lane_sel->retain_mask))) >> p_lane_sel->lo_bit)
        {
            reg_val = (reg_val & p_lane_sel->retain_mask) | ((lane << p_lane_sel->lo_bit) & p_lane_sel->mask);
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg(p_dev, p_lane_sel->reg, reg_val));
        }
    }
    CTC_ERROR_RETURN(_sys_at_serdes_read_reg(p_dev, reg, p_data));
    return CTC_E_NONE;
}

int32 _sys_at_serdes_write_reg_lane(sys_at_serdes_dev_t* p_dev, uint32 reg, 
                                                uint8 reg_type, uint32 data)
{
    _sys_at_serdes_field_t* p_lane_sel = NULL;
    uint32 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 reg_val = 0;
    /* Lane switching is necessary for register adresses from 0 ~ 0x7FFC */
    if((0x8000 > reg) && (SYS_AT_SERDES_REG_LANE == reg_type))
    {
        p_lane_sel = (SYS_AT_SERDES_56G == p_dev->type) ? 
            REG_STR(F_AT56G_LANE_SEL) : REG_STR(F_AT112G_LANE_SEL);
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg(p_dev, p_lane_sel->reg, &reg_val));
        if(lane != (reg_val & (~(p_lane_sel->retain_mask))) >> p_lane_sel->lo_bit)
        {
            reg_val = (reg_val & p_lane_sel->retain_mask) | ((lane << p_lane_sel->lo_bit) & p_lane_sel->mask);
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg(p_dev, p_lane_sel->reg, reg_val));
        }
    }
    CTC_ERROR_RETURN(_sys_at_serdes_write_reg(p_dev, reg, data));
    return CTC_E_NONE;
}

int32 _sys_at_serdes_read_reg_field(sys_at_serdes_dev_t* p_dev, _sys_at_serdes_field_t* p_field, 
                                               uint8 reg_type, uint32* p_data)
{
    uint8  grp_id  = 0;
    uint8  core    = 0;
    uint8  hss_grp = 0;
    int32  ret     = 0;
    uint32 reg_val = 0;
    uint32 mcu_id  = 0;
    
    SYS_CONDITION_RETURN((!p_dev) || (!p_field) || (!p_data), CTC_E_INVALID_PTR);

    grp_id  = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    core    = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    mcu_id  = (grp_id/2);
    hss_grp = grp_id%2;

    SERDES_REG_IO_HW_LOCK(p_dev->lchip, core, mcu_id, hss_grp);
    ret = _sys_at_serdes_read_reg_lane(p_dev, p_field->reg, reg_type, &reg_val);
    if (CTC_E_NONE != ret)
    {
        SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, core, mcu_id, hss_grp);
        return ret;
    }
    *p_data = (reg_val & p_field->mask) >> p_field->lo_bit;
    SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, core, mcu_id, hss_grp);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_write_reg_field(sys_at_serdes_dev_t* p_dev, _sys_at_serdes_field_t* p_field, 
                                                uint8 reg_type, uint32 data)
{
    uint8  grp_id  = 0;
    uint8  core    = 0;
    uint8  hss_grp = 0;
    int32  ret     = 0;
    uint32 reg_val = 0;
    uint32 mcu_id  = 0;

    SYS_CONDITION_RETURN((!p_dev) || (!p_field), CTC_E_INVALID_PTR);

    grp_id  = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    core    = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    mcu_id  = (grp_id/2);
    hss_grp = grp_id%2;

    SERDES_REG_IO_HW_LOCK(p_dev->lchip, core, mcu_id, hss_grp);
    ret = _sys_at_serdes_read_reg_lane(p_dev, p_field->reg, reg_type, &reg_val);
    if (CTC_E_NONE != ret)
    {
        SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, core, mcu_id, hss_grp);
        return ret;
    }
    reg_val = (reg_val & p_field->retain_mask) | ((data << p_field->lo_bit) & p_field->mask);
    ret = _sys_at_serdes_write_reg_lane(p_dev, p_field->reg, reg_type, reg_val);
    if (CTC_E_NONE != ret)
    {
        SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, core, mcu_id, hss_grp);
        return ret;
    }
    
    SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, core, mcu_id, hss_grp);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_poll_reg_field(sys_at_serdes_dev_t* p_dev, _sys_at_serdes_field_t* p_field, 
                                                uint8 reg_type, uint32 exp_value)
{
    uint32 i;
    uint32 data;

    SYS_CONDITION_RETURN((!p_dev) || (!p_field), CTC_E_INVALID_PTR);

    for(i = 0; i < 100000; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, p_field, reg_type, &data));
        if(data == exp_value)
        {
            return CTC_E_NONE;
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "serdes poll reg fail\n");
    return CTC_E_HW_FAIL;
}

void
_sys_at_serdes_get_cpumac_56g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case AT56G_PIN_RESET      :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGlobalRst_f;
            break;
        case AT56G_PIN_SIF_SEL    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssSifSel_f;
            break;
        case AT56G_PIN_DIRECTACCES:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case AT56G_PIN_PHY_MODE   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPhyMode_f;
            break;
        case AT56G_PIN_REFCLK_TX0 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case AT56G_PIN_REFCLK_TX1 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case AT56G_PIN_REFCLK_TX2 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case AT56G_PIN_REFCLK_TX3 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case AT56G_PIN_REFCLK_RX0 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case AT56G_PIN_REFCLK_RX1 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case AT56G_PIN_REFCLK_RX2 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case AT56G_PIN_REFCLK_RX3 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case AT56G_PIN_REFFREF_TX0:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case AT56G_PIN_REFFREF_TX1:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case AT56G_PIN_REFFREF_TX2:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case AT56G_PIN_REFFREF_TX3:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case AT56G_PIN_REFFREF_RX0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case AT56G_PIN_REFFREF_RX1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case AT56G_PIN_REFFREF_RX2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case AT56G_PIN_REFFREF_RX3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case AT56G_PIN_PHY_GEN_TX0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case AT56G_PIN_PHY_GEN_TX1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case AT56G_PIN_PHY_GEN_TX2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case AT56G_PIN_PHY_GEN_TX3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case AT56G_PIN_PHY_GEN_RX0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case AT56G_PIN_PHY_GEN_RX1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case AT56G_PIN_PHY_GEN_RX2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case AT56G_PIN_PHY_GEN_RX3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case AT56G_PIN_PU_PLL0    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case AT56G_PIN_PU_PLL1    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case AT56G_PIN_PU_PLL2    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case AT56G_PIN_PU_PLL3    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case AT56G_PIN_PU_RX0     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case AT56G_PIN_PU_RX1     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case AT56G_PIN_PU_RX2     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case AT56G_PIN_PU_RX3     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case AT56G_PIN_PU_TX0     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case AT56G_PIN_PU_TX1     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case AT56G_PIN_PU_TX2     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case AT56G_PIN_PU_TX3     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case AT56G_PIN_TX_IDLE0   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case AT56G_PIN_TX_IDLE1   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case AT56G_PIN_TX_IDLE2   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case AT56G_PIN_TX_IDLE3   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case AT56G_PIN_PU_IVREF   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case AT56G_PIN_RX_TRAINEN0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case AT56G_PIN_RX_TRAINEN1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case AT56G_PIN_RX_TRAINEN2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case AT56G_PIN_RX_TRAINEN3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case AT56G_PIN_RX_TRAINCO0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane0_f;
            break;
        case AT56G_PIN_RX_TRAINCO1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane1_f;
            break;
        case AT56G_PIN_RX_TRAINCO2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane2_f;
            break;
        case AT56G_PIN_RX_TRAINCO3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane3_f;
            break;
        case AT56G_PIN_RX_TRAINFA0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane0_f;
            break;
        case AT56G_PIN_RX_TRAINFA1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane1_f;
            break;
        case AT56G_PIN_RX_TRAINFA2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane2_f;
            break;
        case AT56G_PIN_RX_TRAINFA3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane3_f;
            break;
        case AT56G_PIN_TX_TRAINEN0:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case AT56G_PIN_TX_TRAINEN1:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case AT56G_PIN_TX_TRAINEN2:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case AT56G_PIN_TX_TRAINEN3:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case AT56G_PIN_TX_TRAINCO0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane0_f;
            break;
        case AT56G_PIN_TX_TRAINCO1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane1_f;
            break;
        case AT56G_PIN_TX_TRAINCO2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane2_f;
            break;
        case AT56G_PIN_TX_TRAINCO3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane3_f;
            break;
        case AT56G_PIN_TX_TRAINFA0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane0_f;
            break;
        case AT56G_PIN_TX_TRAINFA1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane1_f;
            break;
        case AT56G_PIN_TX_TRAINFA2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane2_f;
            break;
        case AT56G_PIN_TX_TRAINFA3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane3_f;
            break;
        case AT56G_PIN_SQ_DET_LPF0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case AT56G_PIN_SQ_DET_LPF1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case AT56G_PIN_SQ_DET_LPF2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case AT56G_PIN_SQ_DET_LPF3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case AT56G_PIN_RX_INIT0   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane0_f;
            break;
        case AT56G_PIN_RX_INIT1   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane1_f;
            break;
        case AT56G_PIN_RX_INIT2   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane2_f;
            break;
        case AT56G_PIN_RX_INIT3   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane3_f;
            break;
        case AT56G_PIN_RX_INITDON0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane0_f;
            break;
        case AT56G_PIN_RX_INITDON1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane1_f;
            break;
        case AT56G_PIN_RX_INITDON2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane2_f;
            break;
        case AT56G_PIN_RX_INITDON3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane3_f;
            break;
        case AT56G_PIN_AVDD_SEL   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssAvddSel_f;
            break;
        case AT56G_PIN_SPD_CFG    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case AT56G_PIN_TX_RST0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case AT56G_PIN_TX_RST1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case AT56G_PIN_TX_RST2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case AT56G_PIN_TX_RST3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case AT56G_PIN_RX_RST0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case AT56G_PIN_RX_RST1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case AT56G_PIN_RX_RST2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case AT56G_PIN_RX_RST3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case AT56G_PIN_PRAM_RESET:
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramReset_f;
            break;
        case AT56G_PIN_FW_READY:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssFwReady_f;
            break;
        case AT56G_PIN_PLL_RDY_RX0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane0_f;
            break;
        case AT56G_PIN_PLL_RDY_RX1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane1_f;
            break;
        case AT56G_PIN_PLL_RDY_RX2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane2_f;
            break;
        case AT56G_PIN_PLL_RDY_RX3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane3_f;
            break;
        case AT56G_PIN_PLL_RDY_TX0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane0_f;
            break;
        case AT56G_PIN_PLL_RDY_TX1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane1_f;
            break;
        case AT56G_PIN_PLL_RDY_TX2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane2_f;
            break;
        case AT56G_PIN_PLL_RDY_TX3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane3_f;
            break;
        case AT56G_PIN_TX_RST_ACK0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane0_f;
            break;
        case AT56G_PIN_TX_RST_ACK1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane1_f;
            break;
        case AT56G_PIN_TX_RST_ACK2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane2_f;
            break;
        case AT56G_PIN_TX_RST_ACK3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane3_f;
            break;
        case AT56G_PIN_RX_RST_ACK0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane0_f;
            break;
        case AT56G_PIN_RX_RST_ACK1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane1_f;
            break;
        case AT56G_PIN_RX_RST_ACK2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane2_f;
            break;
        case AT56G_PIN_RX_RST_ACK3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane3_f;
            break;
        case AT56G_PIN_PRAM_SOC_EN :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramSocEn_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN0 :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN1 :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN2 :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN3 :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN0:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN1:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN2:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN3:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case AT56G_PIN_MCU_CLK:
            tbl_id = CpuMacHssMcuCfg_t;
            fld_id = CpuMacHssMcuCfg_cfgHssMcuFreq_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumReset_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM :
            tbl_id = CpuMacHssPramMon_t;
            fld_id = CpuMacHssPramMon_monPramChecksum_f;
            break;
        case AT56G_PIN_RX_DTL_CLAMP0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane0_f;
            break;
    	case AT56G_PIN_RX_DTL_CLAMP1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane1_f;
            break;
    	case AT56G_PIN_RX_DTL_CLAMP2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane2_f;
            break;
    	case AT56G_PIN_RX_DTL_CLAMP3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane3_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumEn_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumSel_f;
            break;
        case AT56G_PIN_MCU_INIT_DONE :
            tbl_id = CpuMacHssMcuMon_t;
            fld_id = CpuMacHssMcuMon_monHssMcuInitDone_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}

void
_sys_at_serdes_get_56g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case AT56G_PIN_RESET      :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGlobalRst_f;
            break;
        case AT56G_PIN_SIF_SEL    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSifSel_f;
            break;
        case AT56G_PIN_DIRECTACCES:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case AT56G_PIN_PHY_MODE   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPhyMode_f;
            break;
        case AT56G_PIN_REFCLK_TX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case AT56G_PIN_REFCLK_TX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case AT56G_PIN_REFCLK_TX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case AT56G_PIN_REFCLK_TX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case AT56G_PIN_REFCLK_RX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case AT56G_PIN_REFCLK_RX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case AT56G_PIN_REFCLK_RX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case AT56G_PIN_REFCLK_RX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case AT56G_PIN_REFFREF_TX0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case AT56G_PIN_REFFREF_TX1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case AT56G_PIN_REFFREF_TX2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case AT56G_PIN_REFFREF_TX3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case AT56G_PIN_REFFREF_RX0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case AT56G_PIN_REFFREF_RX1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case AT56G_PIN_REFFREF_RX2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case AT56G_PIN_REFFREF_RX3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case AT56G_PIN_PHY_GEN_TX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case AT56G_PIN_PHY_GEN_TX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case AT56G_PIN_PHY_GEN_TX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case AT56G_PIN_PHY_GEN_TX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case AT56G_PIN_PHY_GEN_RX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case AT56G_PIN_PHY_GEN_RX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case AT56G_PIN_PHY_GEN_RX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case AT56G_PIN_PHY_GEN_RX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case AT56G_PIN_PU_PLL0    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case AT56G_PIN_PU_PLL1    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case AT56G_PIN_PU_PLL2    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case AT56G_PIN_PU_PLL3    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case AT56G_PIN_PU_RX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case AT56G_PIN_PU_RX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case AT56G_PIN_PU_RX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case AT56G_PIN_PU_RX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case AT56G_PIN_PU_TX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case AT56G_PIN_PU_TX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case AT56G_PIN_PU_TX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case AT56G_PIN_PU_TX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case AT56G_PIN_TX_IDLE0   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case AT56G_PIN_TX_IDLE1   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case AT56G_PIN_TX_IDLE2   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case AT56G_PIN_TX_IDLE3   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case AT56G_PIN_PU_IVREF   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case AT56G_PIN_RX_TRAINEN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case AT56G_PIN_RX_TRAINEN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case AT56G_PIN_RX_TRAINEN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case AT56G_PIN_RX_TRAINEN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case AT56G_PIN_RX_TRAINCO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane0_f;
            break;
        case AT56G_PIN_RX_TRAINCO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane1_f;
            break;
        case AT56G_PIN_RX_TRAINCO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane2_f;
            break;
        case AT56G_PIN_RX_TRAINCO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane3_f;
            break;
        case AT56G_PIN_RX_TRAINFA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane0_f;
            break;
        case AT56G_PIN_RX_TRAINFA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane1_f;
            break;
        case AT56G_PIN_RX_TRAINFA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane2_f;
            break;
        case AT56G_PIN_RX_TRAINFA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane3_f;
            break;
        case AT56G_PIN_TX_TRAINEN0:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case AT56G_PIN_TX_TRAINEN1:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case AT56G_PIN_TX_TRAINEN2:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case AT56G_PIN_TX_TRAINEN3:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case AT56G_PIN_TX_TRAINCO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane0_f;
            break;
        case AT56G_PIN_TX_TRAINCO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane1_f;
            break;
        case AT56G_PIN_TX_TRAINCO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane2_f;
            break;
        case AT56G_PIN_TX_TRAINCO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane3_f;
            break;
        case AT56G_PIN_TX_TRAINFA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane0_f;
            break;
        case AT56G_PIN_TX_TRAINFA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane1_f;
            break;
        case AT56G_PIN_TX_TRAINFA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane2_f;
            break;
        case AT56G_PIN_TX_TRAINFA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane3_f;
            break;
        case AT56G_PIN_SQ_DET_LPF0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case AT56G_PIN_SQ_DET_LPF1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case AT56G_PIN_SQ_DET_LPF2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case AT56G_PIN_SQ_DET_LPF3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case AT56G_PIN_RX_INIT0   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane0_f;
            break;
        case AT56G_PIN_RX_INIT1   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane1_f;
            break;
        case AT56G_PIN_RX_INIT2   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane2_f;
            break;
        case AT56G_PIN_RX_INIT3   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane3_f;
            break;
        case AT56G_PIN_RX_INITDON0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane0_f;
            break;
        case AT56G_PIN_RX_INITDON1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane1_f;
            break;
        case AT56G_PIN_RX_INITDON2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane2_f;
            break;
        case AT56G_PIN_RX_INITDON3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane3_f;
            break;
        case AT56G_PIN_AVDD_SEL   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssAvddSel_f;
            break;
        case AT56G_PIN_SPD_CFG    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case AT56G_PIN_TX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case AT56G_PIN_TX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case AT56G_PIN_TX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case AT56G_PIN_TX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case AT56G_PIN_RX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case AT56G_PIN_RX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case AT56G_PIN_RX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case AT56G_PIN_RX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case AT56G_PIN_PRAM_RESET:
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramReset_f;
            break;
        case AT56G_PIN_FW_READY:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssFwReady_f;
            break;
        case AT56G_PIN_PLL_RDY_RX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane0_f;
            break;
        case AT56G_PIN_PLL_RDY_RX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane1_f;
            break;
        case AT56G_PIN_PLL_RDY_RX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane2_f;
            break;
        case AT56G_PIN_PLL_RDY_RX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane3_f;
            break;
        case AT56G_PIN_PLL_RDY_TX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane0_f;
            break;
        case AT56G_PIN_PLL_RDY_TX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane1_f;
            break;
        case AT56G_PIN_PLL_RDY_TX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane2_f;
            break;
        case AT56G_PIN_PLL_RDY_TX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane3_f;
            break;
        case AT56G_PIN_TX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane0_f;
            break;
        case AT56G_PIN_TX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane1_f;
            break;
        case AT56G_PIN_TX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane2_f;
            break;
        case AT56G_PIN_TX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane3_f;
            break;
        case AT56G_PIN_RX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane0_f;
            break;
        case AT56G_PIN_RX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane1_f;
            break;
        case AT56G_PIN_RX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane2_f;
            break;
        case AT56G_PIN_RX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane3_f;
            break;
        case AT56G_PIN_PRAM_SOC_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramSocEn_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case AT56G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN0 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN1 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN2 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case AT56G_PIN_TX_GRAYCODE_EN3 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case AT56G_PIN_RX_PRECODE_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case AT56G_PIN_TX_PRECODE_EN3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case AT56G_PIN_MCU_CLK:
            tbl_id = HssMcuCfg_t;
            fld_id = HssMcuCfg_cfgHssMcuFreq_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case AT56G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumReset_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM :
            tbl_id = HssPramMon_t;
            fld_id = HssPramMon_monPramChecksum_f;
            break;
        case AT56G_PIN_RX_DTL_CLAMP0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane0_f;
            break;
        case AT56G_PIN_RX_DTL_CLAMP1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane1_f;
            break;
        case AT56G_PIN_RX_DTL_CLAMP2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane2_f;
            break;
        case AT56G_PIN_RX_DTL_CLAMP3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane3_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumEn_f;
            break;
        case AT56G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumSel_f;
            break;
        case AT56G_PIN_MCU_INIT_DONE :
            tbl_id = HssMcuMon_t;
            fld_id = HssMcuMon_monHssMcuInitDone_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}

void
_sys_at_serdes_get_112g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case AT112G_PIN_RESET      :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGlobalRst_f;
            break;
        case AT112G_PIN_SIF_SEL    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSifSel_f;
            break;
        case AT112G_PIN_DIRECTACCESS:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case AT112G_PIN_PHY_MODE   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPhyMode_f;
            break;
        case AT112G_PIN_REFCLK_TX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case AT112G_PIN_REFCLK_TX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case AT112G_PIN_REFCLK_TX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case AT112G_PIN_REFCLK_TX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case AT112G_PIN_REFCLK_RX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case AT112G_PIN_REFCLK_RX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case AT112G_PIN_REFCLK_RX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case AT112G_PIN_REFCLK_RX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case AT112G_PIN_REF_FREF_TX0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case AT112G_PIN_REF_FREF_TX1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case AT112G_PIN_REF_FREF_TX2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case AT112G_PIN_REF_FREF_TX3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case AT112G_PIN_REF_FREF_RX0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case AT112G_PIN_REF_FREF_RX1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case AT112G_PIN_REF_FREF_RX2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case AT112G_PIN_REF_FREF_RX3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case AT112G_PIN_PHY_GEN_TX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case AT112G_PIN_PHY_GEN_TX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case AT112G_PIN_PHY_GEN_TX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case AT112G_PIN_PHY_GEN_TX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case AT112G_PIN_PHY_GEN_RX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case AT112G_PIN_PHY_GEN_RX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case AT112G_PIN_PHY_GEN_RX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case AT112G_PIN_PHY_GEN_RX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case AT112G_PIN_PU_PLL0    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case AT112G_PIN_PU_PLL1    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case AT112G_PIN_PU_PLL2    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case AT112G_PIN_PU_PLL3    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case AT112G_PIN_PU_RX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case AT112G_PIN_PU_RX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case AT112G_PIN_PU_RX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case AT112G_PIN_PU_RX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case AT112G_PIN_PU_TX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case AT112G_PIN_PU_TX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case AT112G_PIN_PU_TX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case AT112G_PIN_PU_TX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case AT112G_PIN_TX_IDLE0   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case AT112G_PIN_TX_IDLE1   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case AT112G_PIN_TX_IDLE2   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case AT112G_PIN_TX_IDLE3   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case AT112G_PIN_PU_IVREF   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case AT112G_PIN_RX_TRAIN_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case AT112G_PIN_RX_TRAIN_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case AT112G_PIN_RX_TRAIN_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case AT112G_PIN_RX_TRAIN_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case AT112G_PIN_RX_TRAIN_CO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane0_f;
            break;
        case AT112G_PIN_RX_TRAIN_CO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane1_f;
            break;
        case AT112G_PIN_RX_TRAIN_CO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane2_f;
            break;
        case AT112G_PIN_RX_TRAIN_CO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane3_f;
            break;
        case AT112G_PIN_RX_TRAIN_FA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane0_f;
            break;
        case AT112G_PIN_RX_TRAIN_FA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane1_f;
            break;
        case AT112G_PIN_RX_TRAIN_FA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane2_f;
            break;
        case AT112G_PIN_RX_TRAIN_FA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane3_f;
            break;
        case AT112G_PIN_TX_TRAIN_EN0:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case AT112G_PIN_TX_TRAIN_EN1:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case AT112G_PIN_TX_TRAIN_EN2:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case AT112G_PIN_TX_TRAIN_EN3:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case AT112G_PIN_TX_TRAIN_CO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane0_f;
            break;
        case AT112G_PIN_TX_TRAIN_CO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane1_f;
            break;
        case AT112G_PIN_TX_TRAIN_CO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane2_f;
            break;
        case AT112G_PIN_TX_TRAIN_CO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane3_f;
            break;
        case AT112G_PIN_TX_TRAIN_FA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane0_f;
            break;
        case AT112G_PIN_TX_TRAIN_FA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane1_f;
            break;
        case AT112G_PIN_TX_TRAIN_FA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane2_f;
            break;
        case AT112G_PIN_TX_TRAIN_FA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane3_f;
            break;
        case AT112G_PIN_SQ_DET_LPF0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case AT112G_PIN_SQ_DET_LPF1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case AT112G_PIN_SQ_DET_LPF2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case AT112G_PIN_SQ_DET_LPF3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case AT112G_PIN_RX_INIT0   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane0_f;
            break;
        case AT112G_PIN_RX_INIT1   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane1_f;
            break;
        case AT112G_PIN_RX_INIT2   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane2_f;
            break;
        case AT112G_PIN_RX_INIT3   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane3_f;
            break;
        case AT112G_PIN_RX_INITDONE0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane0_f;
            break;
        case AT112G_PIN_RX_INITDONE1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane1_f;
            break;
        case AT112G_PIN_RX_INITDONE2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane2_f;
            break;
        case AT112G_PIN_RX_INITDONE3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane3_f;
            break;
        case AT112G_PIN_AVDD_SEL   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssAvddSel_f;
            break;
        case AT112G_PIN_SPD_CFG    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case AT112G_PIN_PRAM_RESET  :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramReset_f;
            break;
        case AT112G_PIN_PRAM_SOC_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramSocEn_f;
            break;
        case AT112G_PIN_PRAM_SIF_SEL:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPramSifSel_f;
            break;
        case AT112G_PIN_TX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case AT112G_PIN_TX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case AT112G_PIN_TX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case AT112G_PIN_TX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case AT112G_PIN_RX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case AT112G_PIN_RX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case AT112G_PIN_RX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case AT112G_PIN_RX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case AT112G_PIN_FW_READY:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssFwReady_f;
            break;
        case AT112G_PIN_PLL_RDY_RX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane0_f;
            break;
        case AT112G_PIN_PLL_RDY_RX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane1_f;
            break;
        case AT112G_PIN_PLL_RDY_RX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane2_f;
            break;
        case AT112G_PIN_PLL_RDY_RX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane3_f;
            break;
        case AT112G_PIN_PLL_RDY_TX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane0_f;
            break;
        case AT112G_PIN_PLL_RDY_TX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane1_f;
            break;
        case AT112G_PIN_PLL_RDY_TX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane2_f;
            break;
        case AT112G_PIN_PLL_RDY_TX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane3_f;
            break;
        case AT112G_PIN_TX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane0_f;
            break;
        case AT112G_PIN_TX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane1_f;
            break;
        case AT112G_PIN_TX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane2_f;
            break;
        case AT112G_PIN_TX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane3_f;
            break;
        case AT112G_PIN_RX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane0_f;
            break;
        case AT112G_PIN_RX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane1_f;
            break;
        case AT112G_PIN_RX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane2_f;
            break;
        case AT112G_PIN_RX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane3_f;
            break;
        case AT112G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case AT112G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case AT112G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case AT112G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case AT112G_PIN_TX_GRAYCODE_EN0 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case AT112G_PIN_TX_GRAYCODE_EN1 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case AT112G_PIN_TX_GRAYCODE_EN2 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case AT112G_PIN_TX_GRAYCODE_EN3 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case AT112G_PIN_RX_PRECODE_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case AT112G_PIN_RX_PRECODE_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case AT112G_PIN_RX_PRECODE_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case AT112G_PIN_RX_PRECODE_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case AT112G_PIN_TX_PRECODE_EN0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case AT112G_PIN_TX_PRECODE_EN1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case AT112G_PIN_TX_PRECODE_EN2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case AT112G_PIN_TX_PRECODE_EN3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case AT112G_PIN_MCU_CLK:
            tbl_id = HssMcuCfg_t;
            fld_id = HssMcuCfg_cfgHssMcuFreq_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case AT112G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case AT112G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumReset_f;
            break;
        case AT112G_PIN_PRAM_CHECKSUM :
            tbl_id = HssPramMon_t;
            fld_id = HssPramMon_monPramChecksum_f;
            break;
        case AT112G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumEn_f;
            break;
        case AT112G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumSel_f;
            break;
        case AT112G_PIN_MCU_INIT_DONE :
            tbl_id = HssMcuMon_t;
            fld_id = HssMcuMon_monHssMcuInitDone_f;
            break;
        case AT112G_PIN_RX_DTL_CLAMP0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane0_f;
            break;
        case AT112G_PIN_RX_DTL_CLAMP1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane1_f;
            break;
        case AT112G_PIN_RX_DTL_CLAMP2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane2_f;
            break;
        case AT112G_PIN_RX_DTL_CLAMP3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane3_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}

int32 sys_at_serdes_get_pin_tbl(sys_at_serdes_dev_t* p_dev, uint16 pin, uint32* tbl_id, uint32* fld_id)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        if(SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            _sys_at_serdes_get_cpumac_56g_pin_tbl(pin, tbl_id, fld_id);
        }
        else
        {
            _sys_at_serdes_get_56g_pin_tbl(pin, tbl_id, fld_id);
        }
    }
    else
    {
        _sys_at_serdes_get_112g_pin_tbl(pin, tbl_id, fld_id);
    }
    
    return CTC_E_NONE;
}

int32 
_sys_at_serdes_get_pin(sys_at_serdes_dev_t* p_dev, uint16 pin, uint32 *value)
{
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(AT_SERDES_SIM))
    uint8  grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 val[16] = {0};

    CTC_PTR_VALID_CHECK(value);
    CTC_PTR_VALID_CHECK(p_dev);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        if(SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            _sys_at_serdes_get_cpumac_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
        else
        {
            _sys_at_serdes_get_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
    }
    else
    {
        _sys_at_serdes_get_112g_pin_tbl(pin, &tbl_id, &fld_id);
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    DRV_IOR_FIELD(p_dev->lchip, tbl_id, fld_id, value, val);
#endif
    return CTC_E_NONE;
}

uint8 g_print_tbl = 0;
uint8 g_print_serdes_tbl = 0;
/*Warning: all pin must in one tbl!*/
int32
_sys_at_serdes_set_pin_array(sys_at_serdes_dev_t* p_dev, uint8 pin_num, uint16 pin[], uint32 value[])
{  
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(AT_SERDES_SIM))
    uint8  grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tmp_tbl_id = 0;
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 val[16] = {0};
    uint32 val32  = 0;
    uint8  i      = 0;

    sys_at_serdes_get_pin_tbl(p_dev, pin[0], &tbl_id, &fld_id);
    for(i = 1; i < pin_num; i++)
    {
        CTC_ERROR_RETURN(sys_at_serdes_get_pin_tbl(p_dev, pin[i], &tmp_tbl_id, &fld_id));
        if(tbl_id != tmp_tbl_id)
        {
            return CTC_E_INVALID_PARAM; 
        }
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));

    for(i = 0; i < pin_num; i++)
    {
        sys_at_serdes_get_pin_tbl(p_dev, pin[i], &tbl_id, &fld_id);
        val32 = value[i];
        DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val32, val);
    }

    g_print_tbl = 1;
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    g_print_tbl = 0;
#endif
    return CTC_E_NONE;
}

int32 
_sys_at_serdes_set_pin(sys_at_serdes_dev_t* p_dev, uint16 pin, uint32 value)
{
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(AT_SERDES_SIM))
    uint8  grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = SYS_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 val[16] = {0};

    CTC_PTR_VALID_CHECK(p_dev);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        if(SYS_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            _sys_at_serdes_get_cpumac_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
        else
        {
            _sys_at_serdes_get_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
    }
    else
    {
        _sys_at_serdes_get_112g_pin_tbl(pin, &tbl_id, &fld_id);
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &value, val);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    g_print_tbl = 1;
    CTC_ERROR_RETURN(DMPS_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    g_print_tbl = 0;
#endif

    return CTC_E_NONE;
}

int32 _sys_at_serdes_poll_pin(sys_at_serdes_dev_t* p_dev, uint16 pin, uint32 exp_value)
{
    
#if (defined AT_SERDES_SIM || (SDB_MEM_MODEL == SDB_MODE))
    //sal_printf("#polling pin %u, expected value %u\n", pin, exp_value);
    return CTC_E_NONE;
#else
    #if !defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)
    uint32 i;
    uint32 data;


    for(i = 0; i < 100000; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, pin, &data));
        if(data == exp_value)
        {
            return CTC_E_NONE;
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "serdes  poll pin\n");
    return CTC_E_HW_FAIL;
    #else
    return CTC_E_NONE;
    #endif
#endif
}

#define ____SERDES_INIT____


int32 _sys_at_serdes_set_txrx_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{ 
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint16 pin[2] = {};
    uint32 value[2] = {};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                pin[0] = AT56G_PIN_RX_RST0;
                pin[1] = AT56G_PIN_TX_RST0;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 1:
                pin[0] = AT56G_PIN_RX_RST1;
                pin[1] = AT56G_PIN_TX_RST1;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 2:
                pin[0] = AT56G_PIN_RX_RST2;
                pin[1] = AT56G_PIN_TX_RST2;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 3:
            default:
                pin[0] = AT56G_PIN_RX_RST3;
                pin[1] = AT56G_PIN_TX_RST3;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                pin[0] = AT112G_PIN_RX_RST0;
                pin[1] = AT112G_PIN_TX_RST0;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 1:
                pin[0] = AT112G_PIN_RX_RST1;
                pin[1] = AT112G_PIN_TX_RST1;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 2:
                pin[0] = AT112G_PIN_RX_RST2;
                pin[1] = AT112G_PIN_TX_RST2;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 3:
            default:
                pin[0] = AT112G_PIN_RX_RST3;
                pin[1] = AT112G_PIN_TX_RST3;
                value[0] = reset;
                value[1] = reset;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
        }
    }
    return CTC_E_NONE;
}


int32 _sys_at_serdes_set_tx_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_RST0, reset));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_RST1, reset));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_RST2, reset));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_RST3, reset));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_RST0, reset));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_RST1, reset));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_RST2, reset));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_RST3, reset));
                break;
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_rx_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_RST0, reset));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_RST1, reset));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_RST2, reset));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_RST3, reset));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_RST0, reset));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_RST1, reset));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_RST2, reset));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_RST3, reset));
                break;
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_txrx_reset(sys_at_serdes_dev_t* p_dev, uint32* p_tx_rst, uint32* p_rx_rst)
{ 
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 tx_rst = 0;
    uint32 rx_rst = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_RST0, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_RST0, &tx_rst));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_RST1, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_RST1, &tx_rst));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_RST2, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_RST2, &tx_rst));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_RX_RST3, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_RST3, &tx_rst));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_RST0, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_RST0, &tx_rst));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_RST1, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_RST1, &tx_rst));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_RST2, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_RST2, &tx_rst));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_RX_RST3, &rx_rst));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_RST3, &tx_rst));
                break;
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_rx_rst, rx_rst);
    SYS_USW_VALID_PTR_WRITE(p_tx_rst, tx_rst);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_wait_tx_rstdone(sys_at_serdes_dev_t* p_dev, uint32 exp_value)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_TX_RST_ACK0, exp_value));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_TX_RST_ACK1, exp_value));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_TX_RST_ACK2, exp_value));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_TX_RST_ACK3, exp_value));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_TX_RST_ACK0, exp_value));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_TX_RST_ACK1, exp_value));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_TX_RST_ACK2, exp_value));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_TX_RST_ACK3, exp_value));
                break;
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_wait_rx_rstdone(sys_at_serdes_dev_t* p_dev, uint32 exp_value)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_RST_ACK0, exp_value));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_RST_ACK1, exp_value));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_RST_ACK2, exp_value));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_RST_ACK3, exp_value));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_RST_ACK0, exp_value));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_RST_ACK1, exp_value));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_RST_ACK2, exp_value));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_RST_ACK3, exp_value));
                break;
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_pram_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_RESET, reset));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_RESET, reset));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_pram_reset(sys_at_serdes_dev_t* p_dev, uint32* p_value)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PRAM_RESET, p_value));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PRAM_RESET, p_value));
    }
    sal_printf("_sys_at_serdes_get_pram_reset: %u\n", *p_value);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_pram_checksum_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_CHECKSUM_RESET, reset));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_CHECKSUM_RESET, reset));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_pram_checksum_en(sys_at_serdes_dev_t* p_dev, uint32 enable)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_CHECKSUM_EN, enable));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_CHECKSUM_EN, enable));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_pram_checksum_sel(sys_at_serdes_dev_t* p_dev, uint32 cfg_val)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_CHECKSUM_SEL, cfg_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_CHECKSUM_SEL, cfg_val));
    }
    return CTC_E_NONE;   
}

int32 _sys_at_serdes_poll_pram_checksum(sys_at_serdes_dev_t* p_dev, uint32 exp_val)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PRAM_CHECKSUM, exp_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PRAM_CHECKSUM, exp_val));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_poll_mcuinitdone(sys_at_serdes_dev_t* p_dev, uint32 exp_val)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_MCU_INIT_DONE, exp_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_MCU_INIT_DONE, exp_val));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_global_reset(sys_at_serdes_dev_t* p_dev, uint32 reset)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_112G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RESET, reset));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RESET, reset));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_fw_download(sys_at_serdes_dev_t* p_dev, uint8 flag)
{
    uint8  grp_id = AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint32 pram_addr[41] = {
        0x80040000, 0x80080000, 0x80140000, 0x80180000, 0x80240000, 0x80280000, 0x80340000, 0x80380000, 
        0x80440000, 0x80480000, 0x80840000, 0x80880000, 0x80940000, 0x80980000, 0x80a40000, 0x80a80000,
        0x80b40000, 0x80b80000, 0x80c40000, 0x80c80000, 0x81440000, 0x81480000, 0x81340000, 0x81380000, 
        0x81240000, 0x81280000, 0x81140000, 0x81180000, 0x81040000, 0x81080000, 0x81c40000, 0x81c80000, 
        0x81b40000, 0x81b80000, 0x81a40000, 0x81a80000, 0x81940000, 0x81980000, 0x81840000, 0x81880000, 
        0x85d00000
    };
    uint32* p_fw_data = NULL;
    uint32 fw_words = 0;
    uint32 idx;
    uint8  addr_idx = grp_id % 41;
    uint32 core_id = SYS_AT_GET_CORE_ID_BY_SERDES(p_dev->serdes_id);
    uint64 addr = 0;
    uint64 core_bmp = 0;

    if(0 == core_id) /*core 0*/
    {
        core_bmp = (uint64)0x40 << 32;
    }
    else /*core 1*/
    {
        core_bmp = (uint64)0x80 << 32;
    }

    /*use default firmware*/
    if(SYS_AT_SERDES_FW_DEFAULT == flag)
    {
        if(SYS_AT_SERDES_56G == p_dev->type)
        {
            p_fw_data = g_56g_serdes_fw;
            fw_words  = sizeof(g_56g_serdes_fw) / sizeof(uint32);
        }
        else
        {
            p_fw_data = g_112g_serdes_fw;
            fw_words  = sizeof(g_112g_serdes_fw) / sizeof(uint32);
        }
    }
    else  /*todo: use debug firmware*/
    {
#ifdef SERDES_FW_DEBUG
        if(SYS_AT_SERDES_56G == p_dev->type)
        {
            p_fw_data = g_56g_serdes_fw_dbg;
            fw_words  = sizeof(g_56g_serdes_fw_dbg) / sizeof(uint32);
        }
        else
        {
            p_fw_data = g_112g_serdes_fw_dbg;
            fw_words  = sizeof(g_112g_serdes_fw_dbg) / sizeof(uint32);
        }
#else
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "No debug-version firmware.\n");
        return CTC_E_NONE;
#endif
    }

    for(idx = 0; idx < fw_words; idx++)
    {
        //sal_printf("write address 0x%08x 0x%08x\n", pram_addr[addr_idx]+4*idx, p_fw_data[idx]);
        addr = core_bmp | (uint64)(pram_addr[addr_idx]+4*idx);
        CTC_ERROR_RETURN(drv_usw_chip_write(p_dev->lchip, addr, p_fw_data[idx]));
    }

    return CTC_E_NONE;
}

uint32 _sys_at_serdes_set_broadcast(sys_at_serdes_dev_t* p_dev, uint16 state)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_BROADCAST), 
            SYS_AT_SERDES_REG_GRP, state));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_BROADCAST), 
            SYS_AT_SERDES_REG_GRP, state));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_lane_power(sys_at_serdes_dev_t* p_dev, uint32 state)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint16 pin[3]={};
    uint32 value[3];

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    
    if(0 == state)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_train_en(p_dev, 0));
    }

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                pin[0] = AT56G_PIN_PU_PLL0; 
                pin[1] = AT56G_PIN_PU_TX0;
                pin[2] = AT56G_PIN_PU_RX0;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 1:
                pin[0] = AT56G_PIN_PU_PLL1; 
                pin[1] = AT56G_PIN_PU_TX1;
                pin[2] = AT56G_PIN_PU_RX1;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 2:
                pin[0] = AT56G_PIN_PU_PLL2; 
                pin[1] = AT56G_PIN_PU_TX2;
                pin[2] = AT56G_PIN_PU_RX2;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 3:
                pin[0] = AT56G_PIN_PU_PLL3; 
                pin[1] = AT56G_PIN_PU_TX3;
                pin[2] = AT56G_PIN_PU_RX3;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                pin[0] = AT112G_PIN_PU_PLL0; 
                pin[1] = AT112G_PIN_PU_TX0;
                pin[2] = AT112G_PIN_PU_RX0;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 1:
                pin[0] = AT112G_PIN_PU_PLL1; 
                pin[1] = AT112G_PIN_PU_TX1;
                pin[2] = AT112G_PIN_PU_RX1;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 2:
                pin[0] = AT112G_PIN_PU_PLL2; 
                pin[1] = AT112G_PIN_PU_TX2;
                pin[2] = AT112G_PIN_PU_RX2;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            case 3:
                pin[0] = AT112G_PIN_PU_PLL3; 
                pin[1] = AT112G_PIN_PU_TX3;
                pin[2] = AT112G_PIN_PU_RX3;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 3, pin, value));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_lane_power(sys_at_serdes_dev_t* p_dev, uint32* p_pu_pll, uint32* p_pu_tx, uint32* p_pu_rx)
{
    uint8  lane   = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 pu_pll = 0;
    uint32 pu_tx  = 0;
    uint32 pu_rx  = 0;

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_PLL0, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_TX0, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_RX0, &pu_rx));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_PLL1, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_TX1, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_RX1, &pu_rx));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_PLL2, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_TX2, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_RX2, &pu_rx));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_PLL3, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_TX3, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_RX3, &pu_rx));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_PLL0, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_TX0, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_RX0, &pu_rx));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_PLL1, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_TX1, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_RX1, &pu_rx));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_PLL2, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_TX2, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_RX2, &pu_rx));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_PLL3, &pu_pll));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_TX3, &pu_tx));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_RX3, &pu_rx));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_pu_pll, pu_pll);
    SYS_USW_VALID_PTR_WRITE(p_pu_tx, pu_tx);
    SYS_USW_VALID_PTR_WRITE(p_pu_rx, pu_rx);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_ref_freq(sys_at_serdes_dev_t* p_dev, uint32 txFreq, uint32 rxFreq,
                                                                  uint32 txClkSel, uint32 rxClkSel)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_TX0, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_RX0, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_TX0, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_RX0, rxClkSel));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_TX1, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_RX1, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_TX1, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_RX1, rxClkSel));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_TX2, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_RX2, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_TX2, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_RX2, rxClkSel));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_TX3, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFFREF_RX3, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_TX3, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_REFCLK_RX3, rxClkSel));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_TX0, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_RX0, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_TX0, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_RX0, rxClkSel));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_TX1, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_RX1, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_TX1, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_RX1, rxClkSel));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_TX2, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_RX2, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_TX2, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_RX2, rxClkSel));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_TX3, txFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REF_FREF_RX3, rxFreq));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_TX3, txClkSel));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_REFCLK_RX3, rxClkSel));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

uint32 _sys_at_serdes_set_phy_mode(sys_at_serdes_dev_t* p_dev, uint32 state)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PHY_MODE, state));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PHY_MODE, state));
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_txrx_bit_rate(sys_at_serdes_dev_t* p_dev, uint32 tx_spd, uint32 rx_spd)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint16 pin[2]={};
    uint32 value[2];

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                pin[0]   = AT56G_PIN_PHY_GEN_TX0;
                pin[1]   = AT56G_PIN_PHY_GEN_RX0;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 1:
                pin[0]   = AT56G_PIN_PHY_GEN_TX1;
                pin[1]   = AT56G_PIN_PHY_GEN_RX1;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 2:
                pin[0]   = AT56G_PIN_PHY_GEN_TX2;
                pin[1]   = AT56G_PIN_PHY_GEN_RX2;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 3:
                pin[0]   = AT56G_PIN_PHY_GEN_TX3;
                pin[1]   = AT56G_PIN_PHY_GEN_RX3;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                pin[0]   = AT112G_PIN_PHY_GEN_TX0;
                pin[1]   = AT112G_PIN_PHY_GEN_RX0;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 1:
                pin[0]   = AT112G_PIN_PHY_GEN_TX1;
                pin[1]   = AT112G_PIN_PHY_GEN_RX1;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 2:
                pin[0]   = AT112G_PIN_PHY_GEN_TX2;
                pin[1]   = AT112G_PIN_PHY_GEN_RX2;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            case 3:
                pin[0]   = AT112G_PIN_PHY_GEN_TX3;
                pin[1]   = AT112G_PIN_PHY_GEN_RX3;
                value[0] = tx_spd;
                value[1] = rx_spd;
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin_array(p_dev, 2, pin, value));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    /*db update, for dbg only*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_psd_rate_div(p_dev->lchip, p_dev->serdes_id, (uint8)rx_spd));
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_txrx_bit_rate(sys_at_serdes_dev_t* p_dev, uint32* p_tx_spd, uint32* p_rx_spd)
{
    uint32 tx_spd = 0;
    uint32 rx_spd = 0;
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_TX0, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_RX0, &rx_spd));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_TX1, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_RX1, &rx_spd));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_TX2, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_RX2, &rx_spd));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_TX3, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PHY_GEN_RX3, &rx_spd));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_TX0, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_RX0, &rx_spd));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_TX1, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_RX1, &rx_spd));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_TX2, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_RX2, &rx_spd));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_TX3, &tx_spd));
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PHY_GEN_RX3, &rx_spd));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }

    SYS_USW_VALID_PTR_WRITE(p_tx_spd, tx_spd);
    SYS_USW_VALID_PTR_WRITE(p_rx_spd, rx_spd);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_tx_en(sys_at_serdes_dev_t* p_dev, uint32* p_state)
{
    uint8  lane  = AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 state = 0;

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_IDLE0, &state));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_IDLE1, &state));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_IDLE2, &state));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_IDLE3, &state));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_IDLE0, &state));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_IDLE1, &state));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_IDLE2, &state));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_IDLE3, &state));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_state, state == 0 ? 1 : 0);
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_tx_en(sys_at_serdes_dev_t* p_dev, uint16 state)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_IDLE0, state ? 0 : 1));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_IDLE1, state ? 0 : 1));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_IDLE2, state ? 0 : 1));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_IDLE3, state ? 0 : 1));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_IDLE0, state ? 0 : 1));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_IDLE1, state ? 0 : 1));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_IDLE2, state ? 0 : 1));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_IDLE3, state ? 0 : 1));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

uint32 _sys_at_serdes_set_power_ivref(sys_at_serdes_dev_t* p_dev, uint32 state)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PU_IVREF, state));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PU_IVREF, state));
    }
    return CTC_E_NONE;
}

uint32 _sys_at_serdes_get_power_ivref(sys_at_serdes_dev_t* p_dev, uint32* p_state)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PU_IVREF, p_state));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PU_IVREF, p_state));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_data_width(sys_at_serdes_dev_t* p_dev, uint16* p_txwidth, uint16* p_rxwidth)
{
    uint32 tx_sel_bits = 0;
    uint32 tx_pam2_en  = 0;
    uint32 rx_sel_bits = 0;
    uint32 rx_pam2_en  = 0;
    uint32 txdata      = 0;
    uint32 rxdata      = 0;
    uint32 txspeed     = 0;
    uint32 rxspeed     = 0;
    uint32 tx_mbps     = 0;
    uint32 rx_mbps     = 0;
    uint16 tx_width    = 0;
    uint16 rx_width    = 0;

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, &tx_sel_bits));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &tx_pam2_en));
        if(0 == tx_pam2_en)
        {
            if (0 == tx_sel_bits)
                tx_width = AT56G_DATABUS_80BIT;
            else
                tx_width = AT56G_DATABUS_64BIT;
        }
        else
        {
            if (0 == tx_sel_bits)
                tx_width = AT56G_DATABUS_40BIT;
            else
                tx_width = AT56G_DATABUS_32BIT;
        }

        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, &rx_sel_bits));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &rx_pam2_en));
        if(0 == rx_pam2_en)
        {
            if(0 == rx_sel_bits)
            {
                rx_width = AT56G_DATABUS_80BIT;
            }
            else
            {
                rx_width = AT56G_DATABUS_64BIT;
            }
        }
        else
        {
            if(0 == rx_sel_bits)
            {
                rx_width = AT56G_DATABUS_40BIT;
            }
            else
            {
                rx_width = AT56G_DATABUS_32BIT;
            }
        }
    }
    else if(SYS_AT_SERDES_112G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_TX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, &txdata));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, &rxdata));
        CTC_ERROR_RETURN(_sys_at_serdes_get_txrx_bit_rate(p_dev, &txspeed, &rxspeed));
        CTC_ERROR_RETURN(_sys_at_speed_gbps_to_mbps(p_dev, txspeed, &tx_mbps));
        CTC_ERROR_RETURN(_sys_at_speed_gbps_to_mbps(p_dev, rxspeed, &rx_mbps));
        if(tx_mbps > 56250)         /* speed > 56.25 Gbps */
        {
            tx_width = (0 == txdata) ? AT112G_DATABUS_160BIT : AT112G_DATABUS_128BIT;
        }
        else if(tx_mbps > 32000)    /* speed > 32.0 Gbps */
        {
            tx_width = (0 == txdata) ? AT112G_DATABUS_80BIT : AT112G_DATABUS_64BIT;
        }
        else if(tx_mbps > 0)        /* speed > 0.0 Gbps */
        {
            tx_width = (0 == txdata) ? AT112G_DATABUS_40BIT : AT112G_DATABUS_32BIT;
        }
        
        if(rx_mbps > 56250)         /* speed > 56.25Gbps */
        {
            rx_width = (0 == rxdata) ? AT112G_DATABUS_160BIT : AT112G_DATABUS_128BIT;
        }
        else if(rx_mbps > 32000)    /* speed > 32Gbps */
        {
            rx_width = (0 == rxdata) ? AT112G_DATABUS_80BIT : AT112G_DATABUS_64BIT;
        }
        else if(rx_mbps > 0)        /* speed > 0Gbps */
        {
            rx_width = (0 == rxdata) ? AT112G_DATABUS_40BIT : AT112G_DATABUS_32BIT;
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_rxwidth, rx_width);
    SYS_USW_VALID_PTR_WRITE(p_txwidth, tx_width);
    return CTC_E_NONE;
}

uint32 _sys_at_serdes_set_data_width(sys_at_serdes_dev_t* p_dev, uint16 txWidth, uint16 rxWidth)
{
    uint32 txDataSelBits = 0, txDataPAM2En = 0;
    uint32 rxDataSelBits = 0, rxDataPAM2En = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (txWidth)
        {
            case AT56G_DATABUS_80BIT:
                txDataSelBits = 0;
                txDataPAM2En  = 0;
                rxDataSelBits = 0;
                rxDataPAM2En  = 0;
                break;
            case AT56G_DATABUS_40BIT:
                txDataSelBits = 0;
                txDataPAM2En  = 1;
                rxDataSelBits = 0;
                rxDataPAM2En  = 1;
                break;
            case AT56G_DATABUS_64BIT:
                txDataSelBits = 1;
                txDataPAM2En  = 0;
                rxDataSelBits = 1;
                rxDataPAM2En  = 0;
                break;
            case AT56G_DATABUS_32BIT:
            default:
                txDataSelBits = 1;
                txDataPAM2En  = 1;
                rxDataSelBits = 1;
                rxDataPAM2En  = 1;
                break;
        }
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, txDataSelBits));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_PAM2_EN),  
            SYS_AT_SERDES_REG_LANE, txDataPAM2En));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, rxDataSelBits));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_PAM2_EN),  
            SYS_AT_SERDES_REG_LANE, rxDataPAM2En));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_ANA_PAM2_EN),  
            SYS_AT_SERDES_REG_LANE, rxDataPAM2En));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_RX_EQ_PAM2_EN),  
            SYS_AT_SERDES_REG_LANE, rxDataPAM2En));
    }
    else
    {
        switch (txWidth)
        {
            case AT112G_DATABUS_160BIT:
            case AT112G_DATABUS_80BIT:
            case AT112G_DATABUS_40BIT:
                txDataSelBits = 0;
                rxDataSelBits = 0;
                break;
            case AT112G_DATABUS_128BIT:
            case AT112G_DATABUS_64BIT:
            case AT112G_DATABUS_32BIT:
            default:
                txDataSelBits = 1;
                rxDataSelBits = 1;
                break;
        }
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, txDataSelBits));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_RX_SEL_BITS), 
            SYS_AT_SERDES_REG_LANE, rxDataSelBits));
    }
    /*db update, for dbg only*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_psd_data_width(p_dev->lchip, p_dev->serdes_id, (uint8)txWidth));
    return CTC_E_NONE;
}

int32 _sys_at_serdes_disable_rx_init(sys_at_serdes_dev_t* p_dev)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT0, 0));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT1, 0));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT2, 0));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT3, 0));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT0, 0));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT1, 0));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT2, 0));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT3, 0));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_rx_init(sys_at_serdes_dev_t* p_dev)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_INITDON0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT0, 0));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_INITDON1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT1, 0));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_INITDON2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT2, 0));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_RX_INITDON3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_RX_INIT3, 0));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_INITDONE0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT0, 0));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_INITDONE1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT1, 0));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_INITDONE2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT2, 0));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_RX_INITDONE3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_RX_INIT3, 0));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_wait_pll_ready(sys_at_serdes_dev_t* p_dev)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_RX0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_TX0, 1));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_RX1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_TX1, 1));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_RX2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_TX2, 1));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_RX3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT56G_PIN_PLL_RDY_TX3, 1));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_RX0, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_TX0, 1));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_RX1, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_TX1, 1));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_RX2, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_TX2, 1));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_RX3, 1));
                CTC_ERROR_RETURN(_sys_at_serdes_poll_pin(p_dev, AT112G_PIN_PLL_RDY_TX3, 1));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_pll_tx_ready(sys_at_serdes_dev_t* p_dev, uint32* p_tx_rdy)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_TX0, p_tx_rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_TX1, p_tx_rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_TX2, p_tx_rdy));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_TX3, p_tx_rdy));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_TX0, p_tx_rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_TX1, p_tx_rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_TX2, p_tx_rdy));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_TX3, p_tx_rdy));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_pll_rx_ready(sys_at_serdes_dev_t* p_dev, uint32* p_rx_rdy)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_RX0, p_rx_rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_RX1, p_rx_rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_RX2, p_rx_rdy));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_PLL_RDY_RX3, p_rx_rdy));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_RX0, p_rx_rdy));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_RX1, p_rx_rdy));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_RX2, p_rx_rdy));
                break;
            case 3:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_PLL_RDY_RX3, p_rx_rdy));
                break;
            default:
                return CTC_E_HW_FAIL; /* Invalid lane */
        }
    }
    return CTC_E_NONE;
}

/*local digital loopback*/
int32
_sys_at_serdes_get_loopback_local(sys_at_serdes_dev_t* p_dev, uint32* p_en)
{
    SYS_CONDITION_RETURN((!p_en) || (!p_dev), CTC_E_INVALID_PTR);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_D_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_DIG_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    return CTC_E_NONE;
}

/*local digital loopback, or near-end loopback*/
int32
_sys_at_serdes_set_loopback_local(sys_at_serdes_dev_t* p_dev)
{
    SYS_CONDITION_RETURN((!p_dev), CTC_E_INVALID_PTR);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DFE_SQ_EN), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_SQ_DET_EN), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_CLAMPING), 
            SYS_AT_SERDES_REG_LANE, 7));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_A_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ANA_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 1));
    }
    return CTC_E_NONE;
}

/*far-end loopback*/
int32
_sys_at_serdes_get_loopback_external(sys_at_serdes_dev_t* p_dev, uint32* p_en)
{
    SYS_CONDITION_RETURN((!p_en) || (!p_dev), CTC_E_INVALID_PTR);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_D_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_DIG_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    return CTC_E_NONE;
}

/*far-end loopback*/
int32
_sys_at_serdes_set_loopback_external(sys_at_serdes_dev_t* p_dev)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DFE_SQ_EN), SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_SQ_DET_EN), SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_CLAMPING), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_R2T_NO_STOP), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_R2T_RD_START), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_FOFFSET_DIS), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_RX2TX_LPBK), SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_A_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_PU_LB), SYS_AT_SERDES_REG_LANE, 0));
        //CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN), SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ANA_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        //CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(p_dev, FALSE));
    }
    return CTC_E_NONE;
}

/*Local analog serial loopback*/
int32
_sys_at_serdes_get_loopback_internal(sys_at_serdes_dev_t* p_dev, uint32* p_en)
{
    SYS_CONDITION_RETURN((!p_en) || (!p_dev), CTC_E_INVALID_PTR);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_A_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_ANA_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, p_en));
    }
    return CTC_E_NONE;
}

/*Local analog serial loopback*/
int32
_sys_at_serdes_set_loopback_internal(sys_at_serdes_dev_t* p_dev)
{
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(p_dev->lchip, p_dev->serdes_id, DMPS_RX, DMPS_POLARITY_NORM));
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(p_dev->lchip, p_dev->serdes_id, DMPS_TX, DMPS_POLARITY_NORM));
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DFE_SQ_EN), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_SQ_DET_EN), SYS_AT_SERDES_REG_LANE, 0));
        /*skip tx ffe config 0 0 3f 0*/
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DTL_CLAMPING), SYS_AT_SERDES_REG_LANE, 7));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_RX2TX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_A_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_D_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_PU_LB), SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_EN), SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_RX2TX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_DIG_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ANA_TX2RX_LPBK), 
            SYS_AT_SERDES_REG_LANE, 1));
    }

    return CTC_E_NONE;
}

/*
                  +-----------+            +-----------+
Data stream TX --+| SerDes TX |-+>>>>>>>>>>| SerDes RX |-+
                 |+-----------+ |          +-----------+ |
                2|             0|                       1|
                 |+-----------+ |          +-----------+ |
Data stream RX <-+| SerDes RX <-+<<<<<<<<<<| SerDes TX <-+
                  +-----------+            +-----------+

0 - Internal Loopback, local analog serial loopback, which sending local TX data to local RX through all logic of the serdes
1 - External Loopback, or Far-end loopback, which sending local RX data to local TX through all logic of the serdes
2 - Local loopback, local digital parallel loopback, which bypassing all internal logic of the serdes
*/
int32
_sys_at_serdes_set_loopback(uint8 lchip, void* p_data)
{
    uint8 tx_pol            = 0;
    uint8 rx_pol            = 0;
    uint8 port_mac_en       = {0};
    sys_at_serdes_dev_t dev = {0};
    sys_dmps_db_upt_info_t upt_info_p = {0};
    ctc_chip_serdes_loopback_t* p_loopback = (ctc_chip_serdes_loopback_t*)p_data;

    CTC_PTR_VALID_CHECK(p_loopback);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%d\n", p_loopback->serdes_id, p_loopback->mode);*/

    _sys_at_get_serdes_dev(lchip, p_loopback->serdes_id, &dev);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PHYSIC_SERDES, p_loopback->serdes_id);
    DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_MAC_EN);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &upt_info_p));
    DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_MAC_EN, port_mac_en);

    /* no loopback*/
    if(FALSE == p_loopback->enable)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_polarity(lchip, p_loopback->serdes_id, &tx_pol, &rx_pol));
        CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, p_loopback->serdes_id, DMPS_TX, tx_pol));
        CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, p_loopback->serdes_id, DMPS_RX, rx_pol));
        if(SYS_AT_SERDES_112G == dev.type)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_DIG_RX2TX_LPBK), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_ANA_TX2RX_LPBK), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_DIG_TX2RX_LPBK), 
                SYS_AT_SERDES_REG_LANE, 0));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_DFE_SQ_EN), SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_DTL_SQ_DET_EN), SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_DTL_CLAMPING), SYS_AT_SERDES_REG_LANE, 7));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_D_RX2TX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_A_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_D_TX2RX_LPBK), SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_PU_LB), SYS_AT_SERDES_REG_LANE, 0));
        }
        CTC_ERROR_RETURN(_sys_at_serdes_set_force_ready(&dev, 0, 0));

        if(TRUE == port_mac_en)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, TRUE));
        }

    }
    else
    {
        switch(p_loopback->mode)
        {
            case DMPS_SERDES_LPBK_INTERNAL: /* Local analog serial Loopback */
                CTC_ERROR_RETURN(_sys_at_serdes_set_loopback_internal(&dev));
                CTC_ERROR_RETURN(_sys_at_serdes_set_force_ready(&dev, 1, 1));
                break;
            case DMPS_SERDES_LPBK_EXTERNAL: /* Far-end Loopback */
                CTC_ERROR_RETURN(_sys_at_serdes_set_loopback_external(&dev));
                CTC_ERROR_RETURN(_sys_at_serdes_set_force_ready(&dev, 0, 0));
                CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 1));
                break;
            case DMPS_SERDES_LPBK_LOCAL: /* Local digital loopback */
                CTC_ERROR_RETURN(_sys_at_serdes_set_loopback_local(&dev));
                CTC_ERROR_RETURN(_sys_at_serdes_set_force_ready(&dev, 1, 1));
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }
    }

    return CTC_E_NONE;
}

/*
                  +-----------+            +-----------+
Data stream TX --+| SerDes TX |-+>>>>>>>>>>| SerDes RX |-+
                 |+-----------+ |          +-----------+ |
                2|             0|                       1|
                 |+-----------+ |          +-----------+ |
Data stream RX <-+| SerDes RX <-+<<<<<<<<<<| SerDes TX <-+
                  +-----------+            +-----------+

0 - Internal Loopback, local analog serial loopback, which sending local TX data to local RX through all logic of the serdes
1 - External Loopback, or Far-end loopback, which sending local RX data to local TX through all logic of the serdes
2 - Local loopback, local digital parallel loopback, which bypassing all internal logic of the serdes
*/
int32
_sys_at_serdes_get_loopback(uint8 lchip, void* p_data)
{
    uint32 en = 0;
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_loopback_t* p_loopback = (ctc_chip_serdes_loopback_t*)p_data;

    CTC_PTR_VALID_CHECK(p_loopback);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d, mode:%d\n", p_loopback->serdes_id, p_loopback->mode);*/

    _sys_at_get_serdes_dev(lchip, p_loopback->serdes_id, &dev);
    switch(p_loopback->mode)
    {
        case DMPS_SERDES_LPBK_INTERNAL: /* Local analog serial Loopback */
            CTC_ERROR_RETURN(_sys_at_serdes_get_loopback_internal(&dev, &en));
            break;
        case DMPS_SERDES_LPBK_EXTERNAL: /* External Loopback */
            CTC_ERROR_RETURN(_sys_at_serdes_get_loopback_external(&dev, &en));
            break;
        case DMPS_SERDES_LPBK_LOCAL: /* Local digital loopback */
            CTC_ERROR_RETURN(_sys_at_serdes_get_loopback_local(&dev, &en));
            break;
        default:
            break;
    }
    p_loopback->enable = (uint8)en;

    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
_sys_at_serdes_set_training_timer(sys_at_serdes_dev_t* p_dev, uint32 to_ms)
{
    uint32 en = (0 == to_ms) ? 0 : 1;
    uint32 ms = to_ms;
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TX_TIMER_EN), 
            SYS_AT_SERDES_REG_LANE, en));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_TRX_TIMER), 
            SYS_AT_SERDES_REG_LANE, ms));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TRX_TIMEOUT_EN), 
            SYS_AT_SERDES_REG_LANE, en));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TRX_TIMER), 
            SYS_AT_SERDES_REG_LANE, ms));
    }

    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
_sys_at_serdes_get_training_timer(sys_at_serdes_dev_t* p_dev, uint32* to_ms)
{
    uint32 en = 0;
    uint32 ms = 0;
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TX_TIMER_EN), 
            SYS_AT_SERDES_REG_LANE, &en));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_TRX_TIMER), 
            SYS_AT_SERDES_REG_LANE, &ms));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_TRX_TIMEOUT_EN), 
            SYS_AT_SERDES_REG_LANE, &en));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_TRX_TIMER), 
            SYS_AT_SERDES_REG_LANE, &ms));
    }
    SYS_USW_VALID_PTR_WRITE(to_ms, (en ? ms : 0));
    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
_sys_at_serdes_set_training_en(sys_at_serdes_dev_t* p_dev, uint32 en)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        if(en)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(p_dev, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_DFE_SAT_EN), 
                SYS_AT_SERDES_REG_LANE, 0));
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN0, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN0, 1));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN1, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN1, 1));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN2, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN2, 1));
                    break;
                case 3:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN3, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN3, 1));
                    break;
            }
        }
        else
        {
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN0, 0));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN1, 0));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN2, 0));
                    break;
                case 3:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_TX_TRAINEN3, 0));
                    break;
            }
            sal_udelay(1000);
        }
    }
    else
    {
        if(en)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(p_dev, 1));
            /* Disable Tx Eq Force to allow firmware */
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C0_F),   
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C1_F), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C2_F), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C3_F), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C4_F), 
                SYS_AT_SERDES_REG_LANE, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TX_FIR_C5_F), 
                SYS_AT_SERDES_REG_LANE, 0));
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN0, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN0, 1));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN1, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN1, 1));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN2, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN2, 1));
                    break;
                case 3:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN3, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN3, 1));
                    break;
            }
        }
        else
        {
            switch(lane)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN0, 0));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN1, 0));
                    break;
                case 2:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN2, 0));
                    break;
                case 3:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_TX_TRAIN_EN3, 0));
                    break;
            }
            sal_udelay(1000);
        }
    }
    
    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
_sys_at_serdes_get_training_en(sys_at_serdes_dev_t* p_dev, uint32* p_en)
{
    uint8 lane = AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINEN0, p_en));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINEN1, p_en));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINEN2, p_en));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINEN3, p_en));
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_EN0, p_en));
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_EN1, p_en));
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_EN2, p_en));
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_EN3, p_en));
                break;
        }
    }
    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
_sys_at_serdes_get_training_status(sys_at_serdes_dev_t* p_dev, uint16* p_status)
{
    uint8  lane = 0;
    uint32 en   = 0;
    uint32 done = 0;
    uint32 fail = 0;

    SYS_CONDITION_RETURN((!p_status) || (!p_dev), CTC_E_INVALID_PTR);

    lane = AT_SERDES_GET_LANE(p_dev->serdes_id);

    CTC_ERROR_RETURN(_sys_at_serdes_get_training_en(p_dev, &en));
    if(!en)
    {
        *p_status = SYS_PORT_CL72_DISABLE;
        return CTC_E_NONE;
    }

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINCO0, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINFA0, &fail));
                }
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINCO1, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINFA1, &fail));
                }
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINCO2, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINFA2, &fail));
                }
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINCO3, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_TX_TRAINFA3, &fail));
                }
                break;
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_CO0, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_FA0, &fail));
                }
                break;
            case 1:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_CO1, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_FA1, &fail));
                }
                break;
            case 2:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_CO2, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_FA2, &fail));
                }
                break;
            case 3:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_CO3, &done));
                if (1 == done)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_TX_TRAIN_FA3, &fail));
                }
                break;
        }
    }

    *p_status = fail ? SYS_PORT_CL72_FAIL : (done ? SYS_PORT_CL72_OK : SYS_PORT_CL72_PROGRESS);

    return CTC_E_NONE;
}

/*TRX TRAIN*/
int32
sys_at_serdes_set_link_training_en(uint8 lchip, uint16 serdes_id, uint8 enable)
{
    sys_at_serdes_dev_t dev = {0};
    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_set_training_en(&dev, enable));

    return CTC_E_NONE;
}

uint8
_sys_at_serdes_is_pam4_reg(sys_at_serdes_dev_t* p_dev)
{
    uint32 pam2_en  = 0;
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_RX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &pam2_en));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &pam2_en));
    }
    if(0 == pam2_en)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

int32
_sys_at_serdes_get_eye_measpoint(sys_at_serdes_dev_t* p_dev, int32 phase, uint8 volt, uint8 tmb, 
                                            _sys_at_serdes_eye_meas_data_t* p_meas)
{
    uint32 cnt_p_l  = 0;
    uint32 cnt_p_h  = 0;
    uint32 cnt_n_l  = 0;
    uint32 cnt_n_h  = 0;
    uint32 cnt_ep_l = 0;
    uint32 cnt_ep_h = 0;
    uint32 cnt_en_l = 0;
    uint32 cnt_en_h = 0;
    uint8  eye_tmb  = SYS_EYE_PAM4_MID;
    uint32 phase_val = (uint32)phase;
    uint32 volt_val = (uint32)volt;

    CTC_PTR_VALID_CHECK(p_meas);
    
    if(_sys_at_serdes_is_pam4_reg(p_dev))
    {
        eye_tmb = tmb;
    }

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_VOLTAGE), 
            SYS_AT_SERDES_REG_LANE, volt_val));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_PHASE), 
            SYS_AT_SERDES_REG_LANE, phase_val));

        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_EOM_DFE_CALL), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT56G_EOM_DFE_CALL), 
            SYS_AT_SERDES_REG_LANE, 0));

        switch(eye_tmb)
        {
            case SYS_EYE_PAM4_TOP:
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_T_P_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_T_P_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_T_N_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_T_N_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_T_P), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_T_N), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
            case SYS_EYE_PAM4_MID:
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_M_P_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_M_P_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_M_N_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_M_N_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_M_P), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_M_N), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
            case SYS_EYE_PAM4_BOT:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_B_P_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_B_P_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_B_N_3932), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_VC_B_N_3100), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_B_P), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT56G_EOM_EC_B_N), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
        }

        p_meas->phase     = phase;
        p_meas->voltage   = volt;
        p_meas->bit_cnt_u = (((uint64)cnt_p_h) << 32) | cnt_p_l;
        p_meas->be_cnt_u  = cnt_ep_l;
        p_meas->bit_cnt_l = (((uint64)cnt_n_h) << 32) | cnt_n_l;
        p_meas->be_cnt_l  = cnt_en_l;
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ESM_VOLTAGE), 
            SYS_AT_SERDES_REG_LANE, volt_val));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ESM_PHASE), 
            SYS_AT_SERDES_REG_LANE, phase_val));

        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_EOM_CALL_CONV), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT112G_EOM_CALL_CONV), 
            SYS_AT_SERDES_REG_LANE, 0));

        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_EOM_CALL), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT112G_EOM_CALL), 
            SYS_AT_SERDES_REG_LANE, 0));

        
        switch(eye_tmb)
        {
            case SYS_EYE_PAM4_TOP:
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D11_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D10_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D11_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D10_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_TOP_H_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_TOP_L_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_TOP_H_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_TOP_L_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
            case SYS_EYE_PAM4_MID:
                if(!_sys_at_serdes_is_pam4_reg(p_dev))
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D11_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D00_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D11_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D00_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D10_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D01_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D10_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                    CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D01_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                }
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_MID_H_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_ep_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_MID_L_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_MID_H_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_en_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_MID_L_CNT), 
                        SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
            case SYS_EYE_PAM4_BOT:
            default:
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D01_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_D00_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_p_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D01_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_D00_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_n_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_BOT_H_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_BOT_L_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_ep_l));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_BOT_H_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_h));
                CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EOM_N_BOT_L_CNT), 
                    SYS_AT_SERDES_REG_LANE, &cnt_en_l));
                break;
        }

        p_meas->phase     = phase;
        p_meas->voltage   = volt;
        p_meas->bit_cnt_u = cnt_p_h + cnt_p_l;
        p_meas->bit_cnt_l = cnt_n_h + cnt_n_l;
        p_meas->be_cnt_u  = cnt_ep_h + cnt_ep_l;
        p_meas->be_cnt_l  = cnt_en_h + cnt_en_l;
    }

    return CTC_E_NONE;
}

int32 _sys_at_serdes_set_eye_en(sys_at_serdes_dev_t* p_dev, uint32 en)
{

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        if(0 != en)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_PATH_SEL), 
                SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_DFEADAPT), 
                SYS_AT_SERDES_REG_LANE, 0xf));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ADAPT_EVEN), 
                SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ADAPT_ODD), 
                SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_EN), 
                SYS_AT_SERDES_REG_LANE, en));
            CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT56G_EOM_READY), 
                SYS_AT_SERDES_REG_LANE, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_LPNUM), 
                SYS_AT_SERDES_REG_LANE, 0xff));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT56G_ESM_EN), 
                SYS_AT_SERDES_REG_LANE, en));
        }
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_ESM_EN), 
            SYS_AT_SERDES_REG_LANE, en));
        if(0 != en)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT112G_EOM_READY), 
                SYS_AT_SERDES_REG_LANE, 1));
        }
    }
    return CTC_E_NONE;
}

int32 
_sys_at_serdes_get_eye_step_cnt(sys_at_serdes_dev_t* p_dev, uint16 *p_phase_cnt, uint16 *p_volt_cnt)
{
    uint32 rx_spd = 0;
    uint16 phase_cnt = 0;
    uint16 volt_cnt = 0;
    uint8 speed = SERDES_SPEED_0G;
    uint32 pam2_en = 0;
    CTC_ERROR_RETURN(_sys_at_serdes_get_txrx_bit_rate(p_dev, NULL, &rx_spd));
    speed = _sys_at_serdes_get_related_serdes_speed((uint8)rx_spd, p_dev->type);

    switch(speed)
    {
        case SERDES_SPEED_103_125G:
        case SERDES_SPEED_106_25G:
        case SERDES_SPEED_112_5G:
            phase_cnt = 64;
            break;
        case SERDES_SPEED_20_625G:
        case SERDES_SPEED_25_78125G:
        case SERDES_SPEED_28_125G:
        case SERDES_SPEED_26_5625G:
        case SERDES_SPEED_27_34375G:
        case SERDES_SPEED_27_78125G:
        case SERDES_SPEED_37_5G:
        case SERDES_SPEED_39_0625G:
        case SERDES_SPEED_51_5625G:
        case SERDES_SPEED_53_125G:
        case SERDES_SPEED_56_25G:
            phase_cnt = 128;
            break;
        case SERDES_SPEED_10_3125G:
        case SERDES_SPEED_11_40625G:
        case SERDES_SPEED_12_5G:
        case SERDES_SPEED_12_96875G:
        case SERDES_SPEED_10_9375G:
            phase_cnt = 256;
            break;
        case SERDES_SPEED_3_125G:
            phase_cnt = 1024;
            break;
        default:
            phase_cnt = 2048;
            break;
    }

    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        volt_cnt = 64;
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &pam2_en));
        volt_cnt = pam2_en ? 128 : 64;
    }

    SYS_USW_VALID_PTR_WRITE(p_phase_cnt, phase_cnt);
    SYS_USW_VALID_PTR_WRITE(p_volt_cnt,  volt_cnt);

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_eye_margin(uint8 lchip, uint16 serdes_id, uint8 wh_flag, uint8 tmb, uint32 *eye_margin)
{
    int32 phase = 0;
    int32 volt = 0;
    int32 left = 0;
    int32 right = 0;
    int32 upper = 0;
    int32 lower = 0;
    int32 max_phase = 0;
    int32 min_phase = 0;
    int32 max_volt = 0;
    uint16 phase_cnt = 0;
    uint16 volt_cnt = 0;
    _sys_at_serdes_eye_meas_data_t meas = {0};
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_set_eye_en(&dev, 1));

    CTC_ERROR_RETURN(_sys_at_serdes_get_eye_step_cnt(&dev, &phase_cnt, &volt_cnt));

    if(SYS_EYE_HEIGHT == wh_flag)
    {
        max_volt = volt_cnt;
        /* Set default edge values */
        upper = -max_volt;
        lower = max_volt - 1;

        /* Scan up and down */
        for(volt = 0; volt < max_volt; volt++)
        {
            /*using phase = 0 to measure because H and W are isolated. if W scan is performed before H scan, the phase may be set to W/2*/
            CTC_ERROR_RETURN(_sys_at_serdes_get_eye_measpoint(&dev, 0, (uint8)volt, tmb, &meas));

            /* Update once when no bits read or error */
            if((upper == -max_volt) && ((0 == meas.bit_cnt_u) || (meas.be_cnt_u > 0)))
            {
                upper = volt;
            }

            /* Update once when no bits read or error */
            /*API using BER < expected thrd criteria to scan boundary, we just check error free to simplify steps*/
            if((lower == (max_volt - 1)) && ((0 == meas.bit_cnt_l) || (meas.be_cnt_l > 0)))
            {
                lower = -volt;
            }

            /* Stop when both edges are found */
            if((upper != -max_volt) && (lower != (max_volt - 1)))
            {
                break;
            }
        }

        /* Default if either edge did not update */
        /*Differs from API, no edge found means eye closed*/
        if((upper == -max_volt) || (lower == (max_volt - 1)))
        {
            upper = 0;
            lower = 0;
        }
        
        *eye_margin = (uint32)((upper == lower) ? 0 : (upper - lower - 1));
    }
    else
    {
        max_phase = phase_cnt / 2;
        min_phase = -phase_cnt / 2;
        /* Set default edge values */
        left = min_phase;
        right = max_phase;

        /* Scan Left */
        for(phase = 0; phase < max_phase; phase++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_get_eye_measpoint(&dev, phase, 0, tmb, &meas));

            /* Stop when no bits read or error */
            if((0 == meas.bit_cnt_u) || (meas.be_cnt_u > 0) || (0 == meas.bit_cnt_l) || (meas.be_cnt_l > 0))
            {
                left = phase;
                break;
            }
        }

        /* Scan Right */
        for(phase = -1; phase > min_phase; phase--)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_get_eye_measpoint(&dev, phase, 0, tmb, &meas));

            /* Stop when no bits read or error */
            if((0 == meas.bit_cnt_u) || (meas.be_cnt_u > 0) || (0 == meas.bit_cnt_l) || (meas.be_cnt_l > 0))
            {
                right = phase;
                break;
            }
        }

        /* Default if either edge did not update */
        /*Differs from API, no edge found means eye closed*/
        if((left == min_phase) || (right == max_phase))
        {
            left = 0;
            right = 0;
        }

        *eye_margin = (uint32)((left == right) ? 0 : (left - right - 1));
    }

    CTC_ERROR_RETURN(_sys_at_serdes_set_eye_en(&dev, 0));

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_eye(uint8 lchip, void* p_data)
{
    uint8                          tmb_range  = 0;
    uint8                          tmb        = 0;
    uint32                         width_min  = SYS_DMPS_INVALID_U32;
    uint32                         height_min = SYS_DMPS_INVALID_U32;
    uint32                         width      = 0;
    uint32                         height     = 0;
    uint32                         sq_det     = 0;
    uint32                         rx_rdy     = 0;
    sys_at_serdes_dev_t            dev        = {0};
    ctc_chip_serdes_eye_diagram_t* p_eye      = (ctc_chip_serdes_eye_diagram_t*)p_data;
    CTC_PTR_VALID_CHECK(p_eye);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s", __FUNCTION__);
    /*SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"serdes_id:%d\n", p_eye->serdes_id);*/
    
    if(CTC_CHIP_SERDES_EYE_PLOT == p_eye->mode)
    {
        return CTC_E_NOT_SUPPORT;
    }

    _sys_at_get_serdes_dev(lchip, p_eye->serdes_id, &dev);

    if(dev.type == SYS_AT_SERDES_112G)
    {
        p_eye->width  = 0;
        p_eye->height = 0;
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_at_serdes_get_sq_det(&dev, &sq_det));
    CTC_ERROR_RETURN(_sys_at_serdes_get_pll_rx_ready(&dev, &rx_rdy));
    if((1 == sq_det) || (rx_rdy == 0))
    {
        p_eye->width  = 0;
        p_eye->height = 0;
        return CTC_E_NONE;
    }

    tmb_range = _sys_at_serdes_is_pam4_reg(&dev) ? 3 : 1;

    for(tmb = 0; tmb < tmb_range; tmb++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_eye_margin(lchip, p_eye->serdes_id, SYS_EYE_WIDTH, tmb, &width));
        CTC_ERROR_RETURN(_sys_at_serdes_get_eye_margin(lchip, p_eye->serdes_id, SYS_EYE_HEIGHT, tmb, &height));
        if(width < width_min)
        {
            width_min = width;
        }
        if(height < height_min)
        {
            height_min = height;
        }
    }
    p_eye->width  = width_min;
    p_eye->height = height_min;

    return CTC_E_NONE;
}

int32 _sys_at_serdes_get_snr(sys_at_serdes_dev_t* p_dev, uint32* snr_db)
{
    uint32 rxEqMonClkEnData, rxPam2EnData;
    uint32 mseValData;
#ifdef CTC_MATH_FLOATING
    uint64 mseValDataL;
    double log = 0.0;
#endif

    if(SYS_AT_SERDES_112G == p_dev->type)
    {
        *snr_db = 0;
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_EQ_MON_CLK_EN), 
            SYS_AT_SERDES_REG_LANE, &rxEqMonClkEnData));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_EQ_MON_CLK_EN), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_START), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_EN),
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_ADAPT_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_MODE), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_CONT_MODE), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_RD_REQ), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_START), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT112G_MSE_DONE), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_RD_REQ), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_reg_field(p_dev, REG_STR(F_AT112G_MSE_RD_ACK), 
            SYS_AT_SERDES_REG_LANE, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_MSE_VAL), 
            SYS_AT_SERDES_REG_LANE, &mseValData));
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(p_dev, REG_STR(F_AT112G_RX_PAM2_EN), 
            SYS_AT_SERDES_REG_LANE, &rxPam2EnData));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_RD_REQ), 
            SYS_AT_SERDES_REG_LANE, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_MSE_START), 
            SYS_AT_SERDES_REG_LANE, 0));
    
        if(0 == rxEqMonClkEnData)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_EQ_MON_CLK_EN), 
                SYS_AT_SERDES_REG_LANE, 0));
        }
       
        if(0 == mseValData)
        {
            *snr_db = 0;
            return CTC_E_NONE;
        }
        if(1 == rxPam2EnData)
        {
#ifdef CTC_MATH_FLOATING
            mseValDataL = (uint64)mseValData*1000000; /*enlarge to 10e6 to prevent intlog10 inupt 0*/
            log = ((sal_log10(mseValDataL / (9 * 65536)) * 1000) / 16777216) - (6 * 1000);
            *snr_db = (uint32)(-10 * log);
#else
            *snr_db = mseValData;
#endif
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "snr = (uint32)(1000 * (-10.0 * log10((double)%u / ((double)9 * 65536))))\n", 
                mseValData);
        }
        else 
        {
#ifdef CTC_MATH_FLOATING
            mseValDataL = (uint64)mseValData*1000000; /*enlarge to 10e6 to prevent intlog10 inupt 0*/
            log = ((sal_log10(mseValDataL / 65536) * 1000) / 16777216) - (6 * 1000);
            *snr_db = (uint32)(1000 * 7 + (-10 * log));
#else
            *snr_db = mseValData;
#endif
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "snr = (uint32)(1000 * (7 + (-10.0 * log10((double)%u / 65536))))\n", 
                mseValData);
        }
    }
    else
    {
        *snr_db = 0;
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_dfe_en(uint8 lchip, void* p_data)
{
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_cfg_t* p_dfe_param = (ctc_chip_serdes_cfg_t*)p_data;

    CTC_PTR_VALID_CHECK(p_dfe_param);

    _sys_at_get_serdes_dev(lchip, p_dfe_param->serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_DFE_EN), 
            SYS_AT_SERDES_REG_LANE, p_dfe_param->value));
    }
    
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_dfe_en(uint8 lchip, void* p_data)
{
    uint32 value = 0;
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_cfg_t* p_dfe_param = (ctc_chip_serdes_cfg_t*)p_data;

    CTC_PTR_VALID_CHECK(p_dfe_param);

    _sys_at_get_serdes_dev(lchip, p_dfe_param->serdes_id, &dev);

    if(SYS_AT_SERDES_56G == dev.type)
    {    
        CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_DFE_EN), 
            SYS_AT_SERDES_REG_LANE, &value));
    }

    p_dfe_param->value = (uint16)value;

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_msblsb_en(uint8 lchip, uint16 psd, uint8 dir, uint8 en_mode)
{
    sys_at_serdes_dev_t dev = {0};

    _sys_at_get_serdes_dev(lchip, psd, &dev);
    
    if(DMPS_TX == dir)
    {
        switch(en_mode)
        {
            case SYS_MSBLSB_MODE_PRECODER:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                break;
            case SYS_MSBLSB_MODE_POSTCODER:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                }
                break;
            case SYS_MSBLSB_MODE_DISABLE:
            default:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_TXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                break;
        }
    }
    else
    {
        switch(en_mode)
        {
            case SYS_MSBLSB_MODE_PRECODER:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                break;
            case SYS_MSBLSB_MODE_POSTCODER:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 1));
                }
                break;
            case SYS_MSBLSB_MODE_DISABLE:
            default:
                if(SYS_AT_SERDES_56G == dev.type)
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                else
                {
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXDATA_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                    CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_RXD_SWAP), 
                        SYS_AT_SERDES_REG_LANE, 0));
                }
                break;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_msblsb_en(uint8 lchip, uint16 psd, uint8 dir, uint8* p_en_mode)
{
    uint32 val1 = 0;
    uint32 val2 = 0;
    sys_at_serdes_dev_t dev = {0};

    CTC_PTR_VALID_CHECK(p_en_mode);

    _sys_at_get_serdes_dev(lchip, psd, &dev);
    
    if(DMPS_TX == dir)
    {
        if(SYS_AT_SERDES_56G == dev.type)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_TXDATA_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val1));
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_TXD_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val2));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TXDATA_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val1));
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_TXD_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val2));
        }
    }
    else
    {
        if(SYS_AT_SERDES_56G == dev.type)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_RXDATA_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val1));
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT56G_RXD_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val2));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_RXDATA_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val1));
            CTC_ERROR_RETURN(_sys_at_serdes_read_reg_field(&dev, REG_STR(F_AT112G_RXD_SWAP), 
                SYS_AT_SERDES_REG_LANE, &val2));
        }
    }

    if ((0 == val1) && (0 == val2))
    {
        *p_en_mode = SYS_MSBLSB_MODE_DISABLE;
    }
    else if ((1 == val1) && (0 == val2))
    {
        *p_en_mode = SYS_MSBLSB_MODE_PRECODER;
    }
    else if ((0 == val1) && (1 == val2))
    {
        *p_en_mode = SYS_MSBLSB_MODE_POSTCODER;
    }
    else
    {
        *p_en_mode = SYS_MSBLSB_MODE_BUTT;
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_trx_en(uint8 lchip, void* p_value)
{
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_cfg_t* p_cfg = (ctc_chip_serdes_cfg_t*)p_value;

    _sys_at_get_serdes_dev(lchip, p_cfg->serdes_id, &dev);

    if(CTC_EGRESS == p_cfg->dir)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, p_cfg->value));
    }
    else
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s, %d\n", __FUNCTION__, __LINE__);
        return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_trx_en(uint8 lchip, void* p_value)
{
    sys_at_serdes_dev_t dev = {0};
    uint32 en = 0;
    ctc_chip_serdes_cfg_t* p_cfg = (ctc_chip_serdes_cfg_t*)p_value;

    _sys_at_get_serdes_dev(lchip, p_cfg->serdes_id, &dev);

    if(CTC_EGRESS == p_cfg->dir)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_tx_en(&dev, &en));
        p_cfg->value = (uint16)en;
    }
    else
    {
        p_cfg->value = 1;
    }
    return CTC_E_NONE;
}

uint8
_sys_at_serdes_check_valid(uint8 lchip, uint16 serdes_id)
{
    uint32 serdes_speed = 0;
    (void) sys_usw_dmps_db_get_serdes_speed(lchip, serdes_id, &serdes_speed);
    return (serdes_speed ? TRUE : FALSE);
}

int32
_sys_at_serdes_set_reset(uint8 lchip, void* p_data)
{
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_cfg_t* p_rst   = (ctc_chip_serdes_cfg_t*)p_data;

    _sys_at_get_serdes_dev(lchip, p_rst->serdes_id, &dev);

    switch(p_rst->dir)
    {
        case CTC_INGRESS:
            switch(p_rst->value)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 0));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 1));
                    break;
                case 2:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 0));
                    break;
            }
            break;
        case CTC_EGRESS:
            switch(p_rst->value)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 0));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 1));
                    break;
                case 2:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 0));
                    break;
            }
            break;
        case CTC_BOTH_DIRECTION:
        default:
            switch(p_rst->value)
            {
                case 0:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 0));
                    break;
                case 1:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 1));
                    break;
                case 2:
                default:
                    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 1));
                    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 0));
                    break;
            }
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_reset(uint8 lchip, void* p_data)
{
    sys_at_serdes_dev_t dev = {0};
    ctc_chip_serdes_cfg_t* p_rst   = (ctc_chip_serdes_cfg_t*)p_data;
    uint32 tx_rst = 0;
    uint32 rx_rst = 0;

    _sys_at_get_serdes_dev(lchip, p_rst->serdes_id, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_get_txrx_reset(&dev, &tx_rst, &rx_rst));

    switch(p_rst->dir)
    {
        case CTC_INGRESS:
            p_rst->value = (uint8)rx_rst;
            break;
        case CTC_EGRESS:
            p_rst->value = (uint8)tx_rst;
            break;
        case CTC_BOTH_DIRECTION:
        default:
            p_rst->value = (uint8)((tx_rst && rx_rst) ? 1 : 0);
            break;
    }

    return CTC_E_NONE;
}

int32 
sys_at_serdes_set_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    CTC_PTR_VALID_CHECK(p_value);

    switch (chip_prop)
    {
        case CTC_CHIP_PROP_SERDES_PRBS:
            CTC_ERROR_RETURN(_sys_at_serdes_set_prbs(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_FFE:
            CTC_ERROR_RETURN(_sys_at_serdes_set_ffe(lchip, p_value));
            break;
        case CTC_CHIP_PEOP_SERDES_POLARITY:
            CTC_ERROR_RETURN(_sys_at_serdes_set_serdes_polarity(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_LOOPBACK:
            CTC_ERROR_RETURN(_sys_at_serdes_set_loopback(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_P_FLAG:
        case CTC_CHIP_PROP_SERDES_PEAK:
        case CTC_CHIP_PROP_SERDES_DPC:
        case CTC_CHIP_PROP_SERDES_SLEW_RATE:
        case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s, %d\n", __FUNCTION__, __LINE__);
            return CTC_E_NOT_SUPPORT;
        case CTC_CHIP_PROP_SERDES_DFE:
            CTC_ERROR_RETURN(_sys_at_serdes_set_dfe_en(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_CTLE:
            CTC_ERROR_RETURN(_sys_at_serdes_set_ctle(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_PRE_CODING:
            CTC_ERROR_RETURN(_sys_at_serdes_set_precode(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_MAP:
            CTC_ERROR_RETURN(_sys_at_serdes_set_lane_swap(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_EN:
            CTC_ERROR_RETURN(_sys_at_serdes_set_trx_en(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_RESET:
            CTC_ERROR_RETURN(_sys_at_serdes_set_reset(lchip, p_value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_at_serdes_get_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    uint16 serdes_id = 0;
    CTC_PTR_VALID_CHECK(p_value);

    serdes_id = *((uint16*)p_value);
    if (!_sys_at_serdes_check_valid(lchip, serdes_id))
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "This serdes cannot get property\n");
        return CTC_E_NOT_SUPPORT;
    }

    switch (chip_prop)
    {
        case CTC_CHIP_PROP_SERDES_FFE:
            CTC_ERROR_RETURN(_sys_at_serdes_get_ffe(lchip, p_value));
            break;
        case CTC_CHIP_PEOP_SERDES_POLARITY:
            CTC_ERROR_RETURN(_sys_at_serdes_get_serdes_polarity(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_LOOPBACK:
            CTC_ERROR_RETURN(_sys_at_serdes_get_loopback(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_P_FLAG:
        case CTC_CHIP_PROP_SERDES_PEAK:
        case CTC_CHIP_PROP_SERDES_DPC:
        case CTC_CHIP_PROP_SERDES_SLEW_RATE:
        case CTC_CHIP_PROP_SERDES_MAP:
        case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s, %d\n", __FUNCTION__, __LINE__);
            return CTC_E_NOT_SUPPORT;
        case CTC_CHIP_PROP_SERDES_DFE:
            CTC_ERROR_RETURN(_sys_at_serdes_get_dfe_en(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_CTLE:
            CTC_ERROR_RETURN(_sys_at_serdes_get_ctle(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_EYE_DIAGRAM:
            CTC_ERROR_RETURN(_sys_at_serdes_get_eye(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_PRBS:
            CTC_ERROR_RETURN(_sys_at_serdes_get_prbs(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_PRE_CODING:
            CTC_ERROR_RETURN(_sys_at_serdes_get_precode(lchip, p_value));
            break;
        case CTC_CHIP_PROP_PLL_LOCK_STATUS:
            CTC_ERROR_RETURN(_sys_at_serdes_get_pll_lock(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_ID_TO_GPORT:
            CTC_ERROR_RETURN(_sys_at_serdes_get_port_serdes_info(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_EN:
            CTC_ERROR_RETURN(_sys_at_serdes_get_trx_en(lchip, p_value));
            break;
        case CTC_CHIP_PROP_SERDES_RESET:
            CTC_ERROR_RETURN(_sys_at_serdes_get_reset(lchip, p_value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_mcu_freq(sys_at_serdes_dev_t* p_dev, uint32 cfg_val)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_MCU_CLK, cfg_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_MCU_CLK, cfg_val));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_avdd(sys_at_serdes_dev_t* p_dev, uint32 cfg_val)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_AVDD_SEL, cfg_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_AVDD_SEL, cfg_val));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_spd_cfg(sys_at_serdes_dev_t* p_dev, uint32 cfg_val)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_SPD_CFG, cfg_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_SPD_CFG, cfg_val));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_get_spd_cfg(sys_at_serdes_dev_t* p_dev, uint32* p_cfg_val)
{
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT56G_PIN_SPD_CFG, p_cfg_val));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_get_pin(p_dev, AT112G_PIN_SPD_CFG, p_cfg_val));
    }
    return CTC_E_NONE;
}

int32
_sys_at_serdes_download_firmware(sys_at_serdes_dev_t* p_dev)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_SOC_EN, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FW_READY, 0));

        (void)_sys_at_serdes_fw_download(p_dev, SYS_AT_SERDES_FW_DEFAULT);

        /* Check FirmWare Download ok, expect checksum 0 */
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_en(p_dev, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_sel(p_dev, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(p_dev, 0));

        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_PRAM_SOC_EN, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT56G_PIN_FW_READY, 1));
        _sys_at_serdes_wait_ms(p_dev, 1);
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_SOC_EN, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FW_READY, 0));

        (void)_sys_at_serdes_fw_download(p_dev, SYS_AT_SERDES_FW_DEFAULT);

        /* Check FirmWare Download ok, expect checksum 0 */
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_en(p_dev, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_sel(p_dev, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(p_dev, 0));

        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_PRAM_SOC_EN, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(p_dev, AT112G_PIN_FW_READY, 1));
        _sys_at_serdes_wait_ms(p_dev, 1);
    }
    CTC_ERROR_RETURN(_sys_at_serdes_poll_mcuinitdone(p_dev, 1));
    return CTC_E_NONE;
}

int32
sys_at_serdes_fw_download(uint8 lchip, uint16 serdes_id, uint8 flag)
{
    uint8  serdes_type = 0;
    sys_at_serdes_dev_t dev = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s flag %d\n", __FUNCTION__, flag);

    serdes_type = _sys_at_datapath_get_serdes_type(serdes_id);
    _sys_at_serdes_to_dev(lchip, serdes_id, serdes_type, &dev);
    CTC_ERROR_RETURN(_sys_at_serdes_fw_download(&dev, flag));

    return CTC_E_NONE;
}

int32
_sys_at_serdes_set_error_inject(uint8 lchip, uint16 serdes_id, uint8 err_num)
{
    sys_at_serdes_dev_t dev = {0};

    if ((err_num < 1) || (err_num > 8))
    {
        return CTC_E_INVALID_PARAM;
    }

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    
    if(SYS_AT_SERDES_56G == dev.type)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_ADD_ERR_NUM), 
            SYS_AT_SERDES_REG_LANE, (err_num - 1)));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT56G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_ADD_ERR_NUM), 
            SYS_AT_SERDES_REG_LANE, (err_num - 1)));
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 1));
        sal_udelay(5000);
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(&dev, REG_STR(F_AT112G_ADD_ERR_EN), 
            SYS_AT_SERDES_REG_LANE, 0));
    }
    return CTC_E_NONE;
}

#if 0
int32 _sys_at_serdes_56g_power_on(uint8 lchip, sys_at_serdes_power_on_t* p_power_on)
{
    sys_at_serdes_dev_t dev = {0};

    _sys_at_serdes_to_dev(lchip, p_power_on->serdes_id, SYS_AT_SERDES_56G, &dev);

    /* Power up current and voltage reference */
    sal_printf("// ====0. SetPowerIvRef start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_power_ivref(&dev, 1));
    sal_printf("// ====0. SetPowerIvRef end\n");

    sal_printf("// ====1. release reset start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(&dev, 0xffffffff));
    sal_printf("// ====1. release reset end\n");

    /* Set PIN_AVDD_SEL */
    sal_printf("// ====2. Set PIN_AVDD_SEL start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_AVDD_SEL, p_power_on->avdd));
    sal_printf("// ====2. Set PIN_AVDD_SEL end\n");

    sal_printf("// ====3. Set Mcu frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_mcu_freq(&dev, 0x165));
    sal_printf("// ====3. Set Mcu frequency end\n");

    /* Configure Reference Frequency and reference clock source group for all lanes */
    sal_printf("// ====4. Set Reference Frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&dev, p_power_on->ref_freq, p_power_on->ref_freq, 
        p_power_on->ref_clk_sel, p_power_on->ref_clk_sel));
    sal_printf("// ====4. Set Reference Frequency end\n");

    /* Set PIN_SPD_CFG */
    sal_printf("// ====5. Set PIN_SPD_CFG start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_SPD_CFG, p_power_on->spd_cfg));
    sal_printf("// ====5. Set PIN_SPD_CFG end\n");

    /* Set SERDES Mode */
    sal_printf("// ====6. Set SERDES Mode start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_phy_mode(&dev, AT_PHYMODE_SERDES));
    sal_printf("// ====6. Set SERDES Mode end\n");

    /* Configure TX and RX bitrates for all lanes */
    sal_printf("// ====7. Set TX and RX bitrates start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, p_power_on->txrx_speed, p_power_on->txrx_speed));
    sal_printf("// ====7. Set TX and RX bitrates end\n");

    /* Download MCU Firmware */
    sal_printf("// ====8. Download MCU Firmware start\n");
    if (p_power_on->is_load_fw)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_PRAM_SOC_EN, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_FW_READY, 0));
        g_print_tbl = 0;
        (void)_sys_at_serdes_fw_download(&dev);
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(&dev, 0));
        g_print_tbl = 1;
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_PRAM_SOC_EN, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT56G_PIN_FW_READY, 1));
        _sys_at_serdes_wait_ms(&dev, 1);
    }
    sal_printf("// ====8. Download MCU Firmware end\n");

    sal_printf("// ====9. Set Boardcast start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&dev, 0));
    sal_printf("// ====9. Set Boardcast end\n");

    /* Set Data Bus Width for all lanes */
    sal_printf("// ====10 Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, p_power_on->data_width, p_power_on->data_width));

    sal_printf("// ====10a. Set gray code & precode start\n");
    if(AT_IS_SERDES_SPEED_PAM4(_sys_at_serdes_get_related_serdes_speed(p_power_on->txrx_speed, SYS_AT_SERDES_56G)))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_RX, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_TX, 1));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_RX, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_TX, 0));
    }
    sal_printf("// ====10a. Set gray code & precode end\n");

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    sal_printf("// ====11. Power on PHY PLLs, TX and RX start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, 1));
    sal_printf("// ====11. Power on PHY PLLs, TX and RX end\n");

    /* Wait HssRx/Tx Rst Ack */
    sal_printf("// ====12. Wait TX/RX Rst Ack start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_tx_rstdone(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_wait_rx_rstdone(&dev, 1));
    sal_printf("// ====12. Wait TX/RX Rst Ack end\n");
    
    sal_printf("// ====13. Release TX/RX Rst start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 0));
    sal_printf("// ====13. Release TX/RX Rst start\n");
    
    sal_printf("// ====14. Wait TX/RX PLL Ready start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));
    #ifdef AT_SERDES_SIM
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 200000\n");
    #endif
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====14. Wait TX/RX PLL Ready end\n");      
     
    /* Enable TX Output for all lanes */
    sal_printf("// ====15. Enable TX Output start\n");
    if (p_power_on->is_tx_en)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 1));
    }
    sal_printf("// ====15. Enable TX Output end\n");

    /* Toggle RX_INIT */
    sal_printf("// ====16. Toggle RX_INIT start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));
    sal_printf("// ====16. Toggle RX_INIT end\n");
 
    return CTC_E_NONE;
}

int32 _sys_at_serdes_56g_power_on_broadcast(uint8 lchip, sys_at_serdes_power_on_t* p_power_on)
{
    sys_at_serdes_dev_t dev[AT_SERDES_NUM_PER_HSS] = {{0}};
    uint16 i = 0;
    uint16 serdes_base = p_power_on->serdes_id / AT_SERDES_NUM_PER_HSS * AT_SERDES_NUM_PER_HSS;

    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        _sys_at_serdes_to_dev(lchip, serdes_base+i, SYS_AT_SERDES_56G, &(dev[i]));
    }

    sal_printf("\n\n====0. release reset start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&(dev[i]), 0));
    }
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&(dev[0]), 1));
    sal_printf("====0. release reset end\n");

    /* Download MCU Firmware */
    sal_printf("\n\n====1. Download MCU Firmware start\n");
    if (p_power_on->is_load_fw)
    {
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_PRAM_SOC_EN, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_FW_READY, 0));
        }
        (void)_sys_at_serdes_fw_download(&(dev[0]));
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_PRAM_SOC_EN, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_FW_READY, 1));
        }
        _sys_at_serdes_wait_ms(&(dev[0]), 1);
    }
    sal_printf("====1. Download MCU Firmware end\n");

    /* Make sure PHY PLLs, Transmitter and Receiver powered is off for all lanes */
    sal_printf("\n\n====2. Power off start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&(dev[i]), 0));
    }
    sal_printf("====2. Power off end\n");

    /* Set PIN_AVDD_SEL */
    sal_printf("\n\n====3. Set PIN_AVDD_SEL start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_AVDD_SEL, p_power_on->avdd));
    }
    sal_printf("====3. Set PIN_AVDD_SEL end\n");

    /* Configure Reference Frequency and reference clock source group */
    sal_printf("\n\n====4. Set Reference Frequency start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&(dev[i]), p_power_on->ref_freq, p_power_on->ref_freq, 
            p_power_on->ref_clk_sel, p_power_on->ref_clk_sel));
    }
    sal_printf("====4. Set Reference Frequency end\n");

    /* Set SERDES Mode */
    sal_printf("\n\n====5. Set SERDES Mode start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_phy_mode(&(dev[i]), AT_PHYMODE_SERDES));
    }
    sal_printf("====5. Set SERDES Mode end\n");

    /* Set PIN_SPD_CFG */
    sal_printf("\n\n====6. Set PIN_SPD_CFG start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT56G_PIN_SPD_CFG, p_power_on->spd_cfg));
    }
    sal_printf("====6. Set PIN_SPD_CFG end\n");
    
    /* Configure TX and RX bitrates for all lanes */
    sal_printf("\n\n====7. Set TX and RX bitrates start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&(dev[i]), p_power_on->txrx_speed, p_power_on->txrx_speed));
    }
    sal_printf("====7. Set TX and RX bitrates end\n");

    /* Disable TX Output for all lanes */
    sal_printf("\n\n====8. Disable TX Output start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&(dev[i]), 0));
    }
    sal_printf("====8. Disable TX Output end\n");

    /* Power up current and voltage reference */
    sal_printf("\n\n====9. SetPowerIvRef start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_power_ivref(&(dev[i]), 1));
    }
    sal_printf("====9. SetPowerIvRef end\n");

    /* Set Data Bus Width for all lanes */
    sal_printf("\n\n====10. Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&(dev[0]), p_power_on->data_width, p_power_on->data_width));
    sal_printf("====10. Set Data Bus Width end\n");

    sal_printf("\n\n====10a. Set gray code & precode start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        if(AT_IS_SERDES_SPEED_PAM4(_sys_at_serdes_get_related_serdes_speed(p_power_on->txrx_speed, SYS_AT_SERDES_56G)))
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_RX, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_TX, 1));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_RX, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_TX, 0));
        }
    }
    sal_printf("====10a. Set gray code & precode end\n");

    ///TODO: polarity config

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    sal_printf("\n\n====11. Power on PHY PLLs, TX and RX start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&(dev[i]), 1));
        CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&(dev[i])));
    }
    sal_printf("====11. Power on PHY PLLs, TX and RX end\n");

    /* Enable TX Output for all lanes */
    sal_printf("\n\n====12. Enable TX Output start\n");
    if (p_power_on->is_tx_en)
    {
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&(dev[i]), 1));
        }
    }
    sal_printf("====12. Enable TX Output end\n");

    /* Toggle RX_INIT */
    sal_printf("\n\n====13. Toggle RX_INIT start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&(dev[i])));
    }
    sal_printf("\n\n====13. Toggle RX_INIT end\n");

    return CTC_E_NONE;
}

int32 _sys_at_serdes_112g_power_on(uint8 lchip, sys_at_serdes_power_on_t* p_power_on)
{
    sys_at_serdes_dev_t dev = {0};

    _sys_at_serdes_to_dev(lchip, p_power_on->serdes_id, SYS_AT_SERDES_112G, &dev);

    
    /* Power up current and voltage reference */
    sal_printf("// ====0. SetPowerIvRef start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_power_ivref(&dev, 1));
    sal_printf("// ====0. SetPowerIvRef end\n");

    sal_printf("// ====1. release reset start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(&dev, 0xffffffff));
    sal_printf("// ====1. release reset end\n");

    /* Set PIN_AVDD_SEL */
    sal_printf("// ====2. Set PIN_AVDD_SEL start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_AVDD_SEL, p_power_on->avdd));
    sal_printf("// ====2. Set PIN_AVDD_SEL end\n");

    sal_printf("// ====3. Set Mcu frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_mcu_freq(&dev, 0x165));
    sal_printf("// ====3. Set Mcu frequency end\n");

    /* Configure Reference Frequency and reference clock source group for all lanes */
    sal_printf("// ====4. Set Reference Frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&dev, p_power_on->ref_freq, p_power_on->ref_freq, 
        p_power_on->ref_clk_sel, p_power_on->ref_clk_sel));
    sal_printf("// ====4. Set Reference Frequency end\n");

    /* Set PIN_SPD_CFG */
    sal_printf("// ====5. Set PIN_SPD_CFG start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_SPD_CFG, p_power_on->spd_cfg));
    sal_printf("// ====5. Set PIN_SPD_CFG end\n");

    /* Set SERDES Mode */
    sal_printf("// ====6. Set SERDES Mode start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_phy_mode(&dev, AT_PHYMODE_SERDES));
    sal_printf("// ====6. Set SERDES Mode end\n");

    /* Configure TX and RX bitrates for all lanes */
    sal_printf("// ====7. Set TX and RX bitrates start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, p_power_on->txrx_speed, p_power_on->txrx_speed));
    sal_printf("// ====7. Set TX and RX bitrates end\n");

    /* Download MCU Firmware */
    sal_printf("// ====8. Download MCU Firmware start\n");
    if (p_power_on->is_load_fw)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_PRAM_SOC_EN, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_FW_READY, 0));
        g_print_tbl = 0;
        (void)_sys_at_serdes_fw_download(&dev);
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(&dev, 0));
        g_print_tbl = 1;
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_PRAM_SOC_EN, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&dev, AT112G_PIN_FW_READY, 1));
        _sys_at_serdes_wait_ms(&dev, 1);
    }
    sal_printf("// ====8. Download MCU Firmware end\n");

    sal_printf("// ====9. Set Boardcast start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&dev, 0));
    sal_printf("// ====9. Set Boardcast end\n");

    /* Set Data Bus Width for all lanes */
    sal_printf("// ====10 Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, p_power_on->data_width, p_power_on->data_width));
    sal_printf("// ====10. Set Data Bus Width end\n");

    sal_printf("// ====10a. Set gray code & precode start\n");
    if(AT_IS_SERDES_SPEED_PAM4(_sys_at_serdes_get_related_serdes_speed(p_power_on->txrx_speed, SYS_AT_SERDES_112G)))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_RX, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_TX, 1));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_RX, 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, p_power_on->serdes_id, DMPS_TX, 0));
    }
    sal_printf("// ====10a. Set gray code & precode end\n");

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    sal_printf("// ====11. Power on PHY PLLs, TX and RX start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, 1));
    sal_printf("// ====11. Power on PHY PLLs, TX and RX end\n");

    /* Wait HssRx/Tx Rst Ack */
    sal_printf("// ====12. Wait TX/RX Rst Ack start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_tx_rstdone(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_wait_rx_rstdone(&dev, 1));
    sal_printf("// ====12. Wait TX/RX Rst Ack end\n");

    sal_printf("// ====13. Release tx&rx reset start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&dev, 0));
    sal_printf("// ====13. Release tx&rx reset end\n");
        

    sal_printf("// ====14. Wait TX/RX PLL Ready start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====14. Wait TX/RX PLL Ready end\n");      

    #ifdef AT_SERDES_SIM
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 200000\n");    
    #endif

    /* Enable TX Output for all lanes */
    sal_printf("// ====15. Enable TX Output start\n");
    if (p_power_on->is_tx_en)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 1));
    }
    sal_printf("// ====15. Enable TX Output end\n");

    /* Toggle RX_INIT */
    sal_printf("// ====16. Toggle RX_INIT start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));
    sal_printf("// ====16. Toggle RX_INIT end\n");
 
    ///TODO: polarity config

    return CTC_E_NONE;
}

int32 _sys_at_serdes_112g_power_on_broadcast(uint8 lchip, sys_at_serdes_power_on_t* p_power_on)
{
    sys_at_serdes_dev_t dev[AT_SERDES_NUM_PER_HSS] = {{0}};
    uint16 i = 0;
    uint16 serdes_base = p_power_on->serdes_id / AT_SERDES_NUM_PER_HSS * AT_SERDES_NUM_PER_HSS;
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        _sys_at_serdes_to_dev(lchip, serdes_base+i, SYS_AT_SERDES_112G, &(dev[i]));
    }

    sal_printf("\n\n====0. release reset start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_reset(&(dev[i]), 0));
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_reset(&(dev[i]), 0));
    }
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&(dev[0]), 1));
    sal_printf("====0. release reset end\n");

    /* Download MCU Firmware */
    sal_printf("\n\n====1. Download MCU Firmware start\n");
    if (p_power_on->is_load_fw)
    {
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_PRAM_SOC_EN, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_FW_READY, 0));
        }
        (void)_sys_at_serdes_fw_download(&(dev[0]));
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_PRAM_SOC_EN, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_FW_READY, 1));
        }
        _sys_at_serdes_wait_ms(&(dev[0]), 1);
    }
    sal_printf("====1. Download MCU Firmware end\n");

    /* Make sure PHY PLLs, Transmitter and Receiver powered is off for all lanes */
    sal_printf("\n\n====2. Power off start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&(dev[i]), 0));
    }
    sal_printf("====2. Power off end\n");

    /* Set PIN_AVDD_SEL */
    sal_printf("\n\n====3. Set PIN_AVDD_SEL start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_AVDD_SEL, p_power_on->avdd));
    }
    sal_printf("====3. Set PIN_AVDD_SEL end\n");

    /* Configure Reference Frequency and reference clock source group for all lanes */
    sal_printf("\n\n====4. Set Reference Frequency start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&(dev[i]), p_power_on->ref_freq, p_power_on->ref_freq, 
            p_power_on->ref_clk_sel, p_power_on->ref_clk_sel));
    }
    sal_printf("====4. Set Reference Frequency end\n");

    /* Set SERDES Mode */
    sal_printf("\n\n====5. Set SERDES Mode start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_phy_mode(&(dev[i]), AT_PHYMODE_SERDES));
    }
    sal_printf("====5. Set SERDES Mode end\n");

    /* Set PIN_SPD_CFG */
    sal_printf("\n\n====6. Set PIN_SPD_CFG start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_pin(&(dev[i]), AT112G_PIN_SPD_CFG, p_power_on->spd_cfg));
    }
    sal_printf("====6. Set PIN_SPD_CFG end\n");

    /* Configure TX and RX bitrates for all lanes */
    sal_printf("\n\n====7. Set TX and RX bitrates start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&(dev[i]), p_power_on->txrx_speed, 
            p_power_on->txrx_speed));
    }
    sal_printf("====7. Set TX and RX bitrates end\n");

    /* Disable TX Output for all lanes */
    sal_printf("\n\n====8. Disable TX Output start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&(dev[i]), 0));
    }
    sal_printf("====8. Disable TX Output end\n");

    /* Power up current and voltage reference */
    sal_printf("\n\n====9. SetPowerIvRef start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_power_ivref(&(dev[i]), 1));
    }
    sal_printf("====9. SetPowerIvRef end\n");

    /* Set Data Bus Width for all lanes */
    sal_printf("\n\n====10. Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&(dev[0]), p_power_on->data_width, p_power_on->data_width));
    sal_printf("====10. Set Data Bus Width end\n");

    sal_printf("\n\n====10a. Set gray code & precode start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        if(AT_IS_SERDES_SPEED_PAM4(_sys_at_serdes_get_related_serdes_speed(p_power_on->txrx_speed, SYS_AT_SERDES_112G)))
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_RX, 1));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_TX, 1));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_RX, 0));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, dev[i].serdes_id, DMPS_TX, 0));
        }
    }
    sal_printf("====10a. Set gray code & precode end\n");

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    sal_printf("\n\n====11. Power on PHY PLLs, TX and RX start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&(dev[i]), 1));
        CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&(dev[i])));
    }
    sal_printf("====11. Power on PHY PLLs, TX and RX end\n");

    /* Enable TX Output for all lanes */
    sal_printf("\n\n====12. Enable TX Output start\n");
    if (p_power_on->is_tx_en)
    {
        for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&(dev[i]), 1));
        }
    }
    sal_printf("====12. Enable TX Output end\n");

    /* Toggle RX_INIT */
    sal_printf("\n\n====13. Toggle RX_INIT start\n");
    for(i = 0; i < AT_SERDES_NUM_PER_HSS; i++)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&(dev[i])));
    }
    sal_printf("\n\n====13. Toggle RX_INIT end\n");

    return CTC_E_NONE;
}

int32 _sys_at_serdes_power_on_proc(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    uint8 hss_id  = serdes_id / AT_SERDES_NUM_PER_HSS;
    uint8 core_id = SYS_AT_GET_CORE_BY_SERDES(serdes_id);
    uint8 lane_idx = AT_SERDES_GET_LANE(serdes_id);
   
    g_print_tbl = 1;
    
    if(0 == lane_idx)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_power_on_per_hss(lchip, core_id, hss_id));
    }

    CTC_ERROR_RETURN(_sys_at_serdes_power_on_per_lane(lchip, serdes_id, serdes_speed));

    g_print_tbl = 0;
    return CTC_E_NONE;
}


int32
sys_at_serdes_init(uint8 lchip)
{
    char* speed_name[] = {
        "0G", "1.25G", "3.125G", "10.3125G", "11.40625G", "12.5G", 
        "12.96875G", "10.9375G", "25.78125G", "28.125G ", "26.5625G", 
        "27.34375G", "27.78125G", "37.5G", "39.0625G", "51.5625G", 
        "53.125G", "56.25G", "103.125G", "106.25G", "112.5G"
    };
    char* ip_name[] = {"56", "112"};
    ctc_chip_serdes_loopback_t loopback = {0};
    ctc_chip_serdes_prbs_t prbs = {0};
    uint8 i;

    for(i = 0; i < 8; i++)
    {
        temp_soft_table[i].ip_type = temp_soft_table[0].ip_type;
        temp_soft_table[i].init_speed = temp_soft_table[0].init_speed;
        temp_soft_table[i].ds_speed = temp_soft_table[0].ds_speed;
        temp_soft_table[i].anlt_en = temp_soft_table[0].anlt_en;
        temp_soft_table[i].lpbk_int_en = temp_soft_table[0].lpbk_int_en;
        temp_soft_table[i].lpbk_ext_en = temp_soft_table[0].lpbk_ext_en;
        temp_soft_table[i].prbs_tx_en = temp_soft_table[0].prbs_tx_en;
        temp_soft_table[i].prbs_rx_en = temp_soft_table[0].prbs_rx_en;
    }
    
    sal_printf("##################################################################################\n");
    sal_printf("# Case Steps:\n");
    sal_printf("# 1. %sG IP, Serdes 16~19 init power on in %s;\n", ip_name[temp_soft_table[0].ip_type], speed_name[temp_soft_table[0].init_speed]);
    if(temp_soft_table[0].ds_speed != temp_soft_table[0].init_speed)
    {
        sal_printf("# 2. %sG IP, Serdes 16~19 dynamic switch to %s;\n", ip_name[temp_soft_table[0].ip_type], speed_name[temp_soft_table[0].ds_speed]);
    }
    if(temp_soft_table[0].anlt_en)
    {
        sal_printf("# 3. %sG IP, Serdes 16~19 start AN;\n", ip_name[temp_soft_table[0].ip_type]);
        sal_printf("# 4. %sG IP, Serdes 16~19 start LT;\n", ip_name[temp_soft_table[0].ip_type]);
    }
    if(temp_soft_table[0].lpbk_int_en)
    {
        sal_printf("# 5. %sG IP, Serdes 16~19 enable internal loopback (local digital loopback);\n", ip_name[temp_soft_table[0].ip_type]);
    }
    if(temp_soft_table[0].lpbk_ext_en)
    {
        sal_printf("# 6. %sG IP, Serdes 16~19 enable external loopback (far-end loopback);\n", ip_name[temp_soft_table[0].ip_type]);
    }
    if(temp_soft_table[0].prbs_tx_en)
    {
        sal_printf("# 7. %sG IP, Serdes 16~19 enable PRBS31 TX;\n", ip_name[temp_soft_table[0].ip_type]);
    }
    if(temp_soft_table[0].prbs_rx_en)
    {
        sal_printf("# 8. %sG IP, Serdes 16~19 enable PRBS31 RX;\n", ip_name[temp_soft_table[0].ip_type]);
    }
    sal_printf("##################################################################################\n\n\n");
    
    sal_printf("\n\n======= 1. %sG IP, Serdes 16~19 init power on in %s\n", ip_name[temp_soft_table[0].ip_type], speed_name[temp_soft_table[0].init_speed]);
    for(i = 0; i < 8; i++)
    {
        SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u init start! %s\n", temp_soft_table[i].serdes_id, speed_name[temp_soft_table[i].init_speed]);
        CTC_ERROR_RETURN(_sys_at_serdes_power_on_proc(lchip, temp_soft_table[i].serdes_id, temp_soft_table[i].init_speed));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u init end!\n", temp_soft_table[i].serdes_id);
    }

   /* if(temp_soft_table[0].ds_speed != temp_soft_table[0].init_speed)
    {
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ======= 2. %sG IP, Serdes 16~19 dynamic switch to %s\n", ip_name[temp_soft_table[0].ip_type], speed_name[temp_soft_table[0].ds_speed]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            CTC_ERROR_RETURN(_sys_at_serdes_speed_switch_proc(lchip, temp_soft_table[i].serdes_id, temp_soft_table[i].ds_speed, temp_soft_table[i].ip_type));
        }
    }*/

    if(temp_soft_table[0].anlt_en)
    {
        sal_printf("\n\n======= 3. %sG IP, Serdes 16~19 start AN\n", ip_name[temp_soft_table[0].ip_type]);
        sal_printf("#replace with AN config\n");
        sal_printf("#wait for AN complete\n");

        sal_printf("\n\n======= 4. %sG IP, Serdes 16~19 start LT\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            /*CTC_ERROR_RETURN(_sys_at_serdes_speed_switch_proc(lchip, temp_soft_table[i].serdes_id, temp_soft_table[i].ds_speed, temp_soft_table[i].ip_type));*/
            sal_printf("==== serdes %u enable LT start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(sys_at_serdes_set_link_training_en(lchip, temp_soft_table[i].serdes_id, TRUE));
            sal_printf("==== serdes %u enable LT end\n", temp_soft_table[i].serdes_id);
        }
        sal_printf("#wait for LT ready\n");
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            sal_printf("==== serdes %u disable LT start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(sys_at_serdes_set_link_training_en(lchip, temp_soft_table[i].serdes_id, FALSE));
            sal_printf("==== serdes %u disable LT end\n", temp_soft_table[i].serdes_id);
        }
    }
    
    if(temp_soft_table[0].lpbk_int_en)
    {
        sal_printf("\n\n======= 5. %sG IP, Serdes 16~19 enable internal loopback (local digital loopback)\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            loopback.serdes_id = temp_soft_table[i].serdes_id;
            loopback.mode = 0;
            loopback.enable = 1;
            sal_printf("==== serdes %u enable loopback-int start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_set_loopback(lchip, (void*)(&loopback)));
            sal_printf("==== serdes %u enable loopback-int end\n", temp_soft_table[i].serdes_id);
        }
    }
    
    if(temp_soft_table[0].lpbk_ext_en)
    {
        sal_printf("\n\n======= 6. %sG IP, Serdes 16~19 enable external loopback (far-end loopback)\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            loopback.serdes_id = temp_soft_table[i].serdes_id;
            loopback.mode = 1;
            loopback.enable = 1;
            sal_printf("==== serdes %u enable loopback-ext start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_set_loopback(lchip, (void*)(&loopback)));
            sal_printf("==== serdes %u enable loopback-ext end\n", temp_soft_table[i].serdes_id);
        }
    }

    if(temp_soft_table[0].prbs_tx_en)
    {
        sal_printf("\n\n======= 7. %sG IP, Serdes 16~19 enable PRBS31 TX;\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            prbs.serdes_id = temp_soft_table[i].serdes_id;
            prbs.polynome_type = 6;
            prbs.value = 1;
            sal_printf("==== serdes %u enable PRBS31 TX start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_set_tx_prbs(lchip, &prbs));
            sal_printf("==== serdes %u enable PRBS31 TX end\n", temp_soft_table[i].serdes_id);
        }
    }
    
    if(temp_soft_table[0].prbs_rx_en)
    {
        sal_printf("\n\n======= 8. %sG IP, Serdes 16~19 enable PRBS31 RX;\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            prbs.serdes_id = temp_soft_table[i].serdes_id;
            prbs.polynome_type = 6;
            prbs.value = 1;
            sal_printf("==== serdes %u enable PRBS31 RX start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_set_rx_prbs(lchip, &prbs));
            sal_printf("==== serdes %u enable PRBS31 RX end\n", temp_soft_table[i].serdes_id);
            sal_printf("==== serdes %u check PRBS31 RX start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_get_rx_prbs(lchip, &prbs));
            sal_printf("==== serdes %u check PRBS31 RX end\n", temp_soft_table[i].serdes_id);
        }
    }
    
    if(temp_soft_table[0].lpbk_ext_en)
    {
        sal_printf("\n\n======= 9. %sG IP, Serdes 16~19 enable local loopback (local analog loopback)\n", ip_name[temp_soft_table[0].ip_type]);
        for(i = 0; i < 8; i++)
        {
            SYS_CONDITION_CONTINUE(0 == temp_soft_table[i].is_valid);
            loopback.serdes_id = temp_soft_table[i].serdes_id;
            loopback.mode = 2;
            loopback.enable = 1;
            sal_printf("==== serdes %u enable loopback-loc start\n", temp_soft_table[i].serdes_id);
            CTC_ERROR_RETURN(_sys_at_serdes_set_loopback(lchip, (void*)(&loopback)));
            sal_printf("==== serdes %u enable loopback-loc end\n", temp_soft_table[i].serdes_id);
        }
    }

    return CTC_E_NONE;
}


#endif

int32 _sys_at_serdes_power_on_per_hss(uint8 lchip, uint8 core_id, uint8 hss_id)
{
#ifdef AT_SERDES_SIM
    uint32 apb_cfg_addr[41] = {
        0x80064210, 0x800a4210, 0x80164210, 0x801a4210, 0x80264210, 0x802a4210, 0x80364210, 0x803a4210, 
        0x80464210, 0x804a4210, 0x80864210, 0x808a4210, 0x80964210, 0x809a4210, 0x80a64210, 0x80aa4210, 
        0x80b64210, 0x80ba4210, 0x80c64210, 0x80ca4210, 0x81464210, 0x814a4210, 0x81364210, 0x813a4210, 
        0x81264210, 0x812a4210, 0x81164210, 0x811a4210, 0x81064210, 0x810a4210, 0x81c64210, 0x81ca4210, 
        0x81b64210, 0x81ba4210, 0x81a64210, 0x81aa4210, 0x81964210, 0x819a4210, 0x81864210, 0x818a4210, 
        0x85d222c8
    };

    uint32 cfg_addr;
    uint32 cfg_addr1;
#endif
    uint8  avdd;
    uint8  spd_cfg;
    sys_at_serdes_dev_t dev = {0};
    uint16 serdes_id = (SYS_AT_HSS_NUM_PER_CORE == hss_id) ? ((0 == core_id) ? AT_SERDES_CPUMAC_START_ID_CORE0 : AT_SERDES_CPUMAC_START_ID_CORE1) :
                        (core_id * SYS_AT_NW_SERDES_NUM_PER_CORE + hss_id * AT_SERDES_NUM_PER_HSS);
#ifndef AT_SERDES_SIM        
    uint8  serdes_type = _sys_at_datapath_get_serdes_type(serdes_id);
#else
    uint8  serdes_type = temp_soft_table[0].ip_type;
#endif

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// power on per hss init , hss %d !!!\n", hss_id);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    if(SYS_AT_SERDES_56G == serdes_type)
    {
       avdd = AT56G_AVDD_1P2V; 
       spd_cfg = AT56G_SPD_CFG_4_PLL;
    }
    else
    {
        avdd = AT112G_AVDD_1P1V;
        spd_cfg = AT112G_SPD_CFG_4_PLL;
    }

    _sys_at_serdes_to_dev(lchip, serdes_id, serdes_type, &dev);

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. SetPowerIvRef start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_power_ivref(&dev, 1));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. SetPowerIvRef end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. release reset start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_set_global_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_reset(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_reset(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_set_pram_checksum_reset(&dev, 0));
    if ((!CTC_WB_ENABLE(lchip)) || (CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_poll_pram_checksum(&dev, 0xffffffff));
    }
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. release reset end\n");

    /* Set PIN_AVDD_SEL */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Set PIN_AVDD_SEL start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_avdd(&dev, avdd));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Set PIN_AVDD_SEL end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set Mcu frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_mcu_freq(&dev, 0x165));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set Mcu frequency end\n");
   
    /* Set PIN_SPD_CFG */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Set PIN_SPD_CFG start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_spd_cfg(&dev, spd_cfg));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Set PIN_SPD_CFG end\n");

    /* Set SERDES Mode */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Set SERDES Mode start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_phy_mode(&dev, AT_PHYMODE_SERDES));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Set SERDES Mode end\n");
    
    /* Download MCU Firmware */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====8. Download MCU Firmware start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_download_firmware(&dev));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====8. Download MCU Firmware end\n");

    /* For simulation, broadcast config fast power on */
#ifdef AT_SERDES_SIM
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&dev, 1));

    cfg_addr  = apb_cfg_addr[hss_id];
    cfg_addr1 = cfg_addr + 4; 

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"loop 1 1 begin\n");
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"reg_write %x 00000002\n", cfg_addr);
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"endloop\n");
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"loop 1 1 begin\n");
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"reg_write %x 0004a350\n", cfg_addr1);
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"endloop\n");
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 210\n");
    
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&dev, 0));
#endif

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====9. Set Boardcast start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_broadcast(&dev, 0));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====9. Set Boardcast end\n");
    
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// power on per hss end , hss %d !!!\n", hss_id);
    
    return CTC_E_NONE;
}

uint8 _sys_at_serdes_get_data_width_by_speed(uint16 serdes_id, uint8 serdes_speed)
{
    uint8  ip_type  = _sys_at_datapath_get_serdes_type(serdes_id);
    uint8  data_bus = 0;
    switch(serdes_speed)
    {
        case SERDES_SPEED_1_25G    :
        case SERDES_SPEED_3_125G   :
        case SERDES_SPEED_10_3125G :
        case SERDES_SPEED_11_40625G:
        case SERDES_SPEED_12_5G    :
        case SERDES_SPEED_12_96875G:
        case SERDES_SPEED_10_9375G :
        case SERDES_SPEED_20_625G:
        case SERDES_SPEED_25_78125G:
        case SERDES_SPEED_28_125G  :
        case SERDES_SPEED_26_5625G :
        case SERDES_SPEED_27_34375G:
        case SERDES_SPEED_27_78125G:
            if(SYS_AT_SERDES_56G == ip_type)
            {
                data_bus = AT56G_DATABUS_32BIT;
            }
            else
            {
                data_bus = AT112G_DATABUS_32BIT;
            }
            break;
        case SERDES_SPEED_51_5625G :
        case SERDES_SPEED_53_125G  :
        case SERDES_SPEED_56_25G   :
        case SERDES_SPEED_42_5G   :
            if(SYS_AT_SERDES_56G == ip_type)
            {
                data_bus = AT56G_DATABUS_64BIT;
            }
            else
            {
                data_bus = AT112G_DATABUS_64BIT;
            }
            break;
        case SERDES_SPEED_103_125G :
        case SERDES_SPEED_106_25G  :
        case SERDES_SPEED_112_5G   :
            if(SYS_AT_SERDES_56G == ip_type)
            {
                data_bus = SYS_DMPS_INVALID_U8; /*impossible*/
            }
            else
            {
                data_bus = AT112G_DATABUS_128BIT;
            }
            break;
        case SERDES_SPEED_0G       :
        default:
            data_bus = SYS_DMPS_INVALID_U8;
            break;
    }
    return data_bus;
}

int32 _sys_at_serdes_tx_train_pam4_preset_sel(sys_at_serdes_dev_t* p_dev, uint32 preset_n)
{
    if((TX_TRAIN_PAM4_PRESET_BUTT <= preset_n) || (TX_TRAIN_PAM4_PRESET1 > preset_n))
    {
        return CTC_E_INVALID_PARAM;
    }
    
    if(SYS_AT_SERDES_56G == p_dev->type)
    {
        /*56G not support*/
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_write_reg_field(p_dev, REG_STR(F_AT112G_TXFFE_PRESET_EXT), 
            SYS_AT_SERDES_REG_LANE, preset_n));
    }
    return CTC_E_NONE;
}

uint8 _sys_at_serdes_speed_switch_is_lane_ok(uint8 lchip, uint16 serdes_id)
{
    int32  ret      = CTC_E_NONE;
    uint8  core_id  = SYS_AT_GET_CORE_ID_BY_SERDES(serdes_id);
    uint32 index    = 0;
    uint32 inst_id  = SYS_AT_GET_PSD_SC(serdes_id);
    uint32 cmd      = 0;
    AnethAdvAbility_m ability_reg;

    index = DRV_INS(inst_id, 0);
    cmd   = DRV_IOR(AnethAdvAbility_t, DRV_ENTRY_FLAG);
    ret = DMPS_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &ability_reg);

    return (CTC_E_NONE == ret ? TRUE : FALSE);
}

int32 _sys_at_serdes_speed_switch_proc(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    uint8  try_time = 3;
    uint8  done_flag = FALSE;
    uint8  data_width;
    uint32 prbs_en = 0;
    sys_at_serdes_dev_t dev = {0};
#ifndef AT_SERDES_SIM        
    uint8  ip_type = _sys_at_datapath_get_serdes_type(serdes_id);
#else
    uint8  ip_type = temp_soft_table[0].ip_type;
#endif
    uint32 txrx_speed = _sys_at_serdes_get_related_txrx_speed(serdes_speed, ip_type);
    ctc_chip_serdes_ffe_t ffe = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    _sys_at_serdes_to_dev(lchip, serdes_id, ip_type, &dev);

    /*disable tx/rx train before reset*/
    CTC_ERROR_RETURN(_sys_at_serdes_set_training_en(&dev, 0));
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_train_en(&dev, 0));
    while(try_time--)
    {
        if(SERDES_SPEED_0G == serdes_speed)
        {
            CTC_ERROR_RETURN(_sys_at_serdes_get_prbs_rx_enable(&dev, &prbs_en));
            if(prbs_en)
            {
                CTC_ERROR_RETURN(_sys_at_serdes_set_prbs_rx_disable(&dev));
            }

            ffe.serdes_id = serdes_id;
            CTC_ERROR_RETURN(_sys_at_serdes_get_txeq_param(lchip, &ffe));

            data_width = _sys_at_serdes_get_data_width_by_speed(serdes_id, SERDES_SPEED_25_78125G);
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, data_width, data_width));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Power off start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, FALSE));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Power off end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Set TX and RX bitrates start\n");
            txrx_speed = (SYS_AT_SERDES_56G == ip_type) ? AT56G_SERDES_25P7812G : AT112G_SERDES_25P78125G;
            CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Set TX and RX bitrates end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, FALSE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, FALSE));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Reset reset_core start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 1));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Reset reset_core end\n");

            if(CTC_E_NONE != _sys_at_serdes_wait_rx_rstdone(&dev, 1))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "RX RST fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_RX_RST_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            if(CTC_E_NONE != _sys_at_serdes_wait_tx_rstdone(&dev, 1))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "TX RST fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_TX_RST_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            done_flag = TRUE;
            CTC_ERROR_RETURN(_sys_at_serdes_set_txeq_param(lchip, &ffe));
        }
        else
        {
            data_width = _sys_at_serdes_get_data_width_by_speed(serdes_id, serdes_speed);
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, data_width, data_width));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width end\n");

            ffe.serdes_id = serdes_id;
            CTC_ERROR_RETURN(_sys_at_serdes_get_txeq_param(lchip, &ffe));
            
            CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 1));

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Wait TX/RX Rst Ack start\n");
            if(CTC_E_NONE != _sys_at_serdes_wait_rx_rstdone(&dev, 1))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "RX RST fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_RX_RST_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            if(CTC_E_NONE != _sys_at_serdes_wait_tx_rstdone(&dev, 1))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "TX RST fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_TX_RST_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Wait TX/RX Rst Ack end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Release tx&rx reset start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 0));

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Release tx&rx reset end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code start\n");

            CTC_ERROR_RETURN(_sys_at_serdes_set_txeq_param(lchip, &ffe));

            if(AT_IS_SERDES_SPEED_PAM4(serdes_speed))
            {
                CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, TRUE));
                CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, TRUE));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, FALSE));
                CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, FALSE));
            }
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set TX and RX bitrates start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set TX and RX bitrates end\n");

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Power on PHY PLLs, TX and RX start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, TRUE));

            if(CTC_E_NONE != _sys_at_serdes_wait_pll_ready(&dev))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "PLL RDY fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_PLL_RDY_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Power on PHY PLLs, TX and RX end\n");

            CTC_ERROR_RETURN(_sys_at_serdes_set_txeq_param(lchip, &ffe));

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Toggle RX_INIT start\n");
            CTC_ERROR_RETURN(_sys_at_serdes_disable_rx_init(&dev));
            if(CTC_E_NONE != _sys_at_serdes_set_rx_init(&dev))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "RX INIT fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_RX_INIT_FAIL, try_time);
                done_flag = FALSE;
                continue;
            }
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Toggle RX_INIT end\n");

            if(AT_IS_SERDES_SPEED_PAM4(serdes_speed))
            {
                CTC_ERROR_RETURN(_sys_at_serdes_tx_train_pam4_preset_sel(&dev, TX_TRAIN_PAM4_PRESET3));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_at_serdes_tx_train_pam4_preset_sel(&dev, TX_TRAIN_PAM4_PRESET1));
            }

            if(_sys_at_serdes_speed_switch_is_lane_ok(lchip, serdes_id))
            {
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_IS_LANE_OK, 1);
            }
            else
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Lane OK fail, try %u more time!\n", try_time);
                sys_usw_mac_link_log_record(lchip, serdes_id, SYS_MAC_LOG_IS_LANE_OK, 0);
                done_flag = FALSE;
                continue;
            }

            done_flag = TRUE;
        }
        SYS_CONDITION_BREAK(done_flag);
    }

    return CTC_E_NONE;
}

int32
_sys_at_serdes_check_and_recover_pll_ready(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    uint32 pll_tx_rdy = 0;
    uint8  ip_type = _sys_at_datapath_get_serdes_type(serdes_id);
    sys_at_serdes_dev_t dev = {0};

    _sys_at_serdes_to_dev(lchip, serdes_id, ip_type, &dev);

    CTC_ERROR_RETURN(_sys_at_serdes_get_pll_tx_ready(&dev, &pll_tx_rdy));

    if (pll_tx_rdy)
    {
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_at_serdes_speed_switch_proc(lchip, serdes_id, serdes_speed));

    return CTC_E_NONE;
}

int32 _sys_at_serdes_lane_power_on_pre_cfg(uint8 lchip, uint16 serdes_id)
{
    uint8  ref_clk_sel;
    uint8  ref_freq;
    uint8  tx_pol = 0;
    uint8  rx_pol = 0;
    sys_at_serdes_dev_t dev = {0};
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// power on per lane init , serdes %d !!!\n", serdes_id);

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    if(SYS_AT_SERDES_56G == dev.type)
    {
        ref_clk_sel = AT56G_REFCLK_SEL_G1;
        ref_freq = AT56G_REFFREQ_156MHZ;
    }
    else
    {
        ref_clk_sel = AT112G_REFCLK_SELGROUP1;
        ref_freq = AT112G_REFFREQ156P25MHZ;
    }

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Set Reference Frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&dev, ref_freq, ref_freq, ref_clk_sel, ref_clk_sel));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Set Reference Frequency end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set TX and RX polarity start\n");
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_polarity(lchip, serdes_id, &tx_pol, &rx_pol));
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, serdes_id, DMPS_TX, tx_pol));
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, serdes_id, DMPS_RX, rx_pol));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set TX and polarity end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set precode start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_RX, FALSE));
    CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_TX, FALSE));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set precode end\n");

    return CTC_E_NONE;
}

int32 _sys_at_serdes_lane_power_on_cfg(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    sys_at_serdes_dev_t dev = {0};
    uint32 txrx_speed = 0;
    uint8  data_width = _sys_at_serdes_get_data_width_by_speed(serdes_id, serdes_speed);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    
    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    txrx_speed = _sys_at_serdes_get_related_txrx_speed(serdes_speed, dev.type);
    
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, data_width, data_width));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====0. Set Data Bus Width end\n");
    
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 1));

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Wait TX/RX Rst Ack start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_rx_rstdone(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_wait_tx_rstdone(&dev, 1));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Wait TX/RX Rst Ack end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Release tx&rx reset start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 0));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Release tx&rx reset end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code start\n");
    if(AT_IS_SERDES_SPEED_PAM4(serdes_speed))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, TRUE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, TRUE));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, FALSE));
    }
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set gray code end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set TX and RX bitrates start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set TX and RX bitrates end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Power on PHY PLLs, TX and RX start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, TRUE));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Power on PHY PLLs, TX and RX end\n");

    return CTC_E_NONE;
}

int32 _sys_at_serdes_lane_power_on_post_cfg(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    sys_at_serdes_dev_t dev = {0};
    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Toggle RX_INIT start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Toggle RX_INIT end\n");

    if(AT_IS_SERDES_SPEED_PAM4(serdes_speed))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_tx_train_pam4_preset_sel(&dev, TX_TRAIN_PAM4_PRESET3));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_tx_train_pam4_preset_sel(&dev, TX_TRAIN_PAM4_PRESET1));
    }

    return CTC_E_NONE;
}

#if 0
int32 _sys_at_serdes_power_on_per_lane(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    uint32 txrx_speed = 0;
    uint8  ref_clk_sel;
    uint8  ref_freq;
    uint8  data_width;
    uint8  tx_pol = 0;
    uint8  rx_pol = 0;
    sys_at_serdes_dev_t dev = {0};


#ifndef AT_SERDES_SIM        
    uint8  ip_type = _sys_at_datapath_get_serdes_type(serdes_id);
#else
    uint8  ip_type = temp_soft_table[0].ip_type;
#endif
   
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// power on per lane init , serdes %d !!!\n", serdes_id);

    if(SYS_AT_SERDES_56G == ip_type)
    {       
        data_width = AT56G_DATABUS_32BIT;        
        ref_clk_sel = AT56G_REFCLK_SEL_G1;
        ref_freq = AT56G_REFFREQ_156MHZ;
    }
    else
    {
        data_width = AT112G_DATABUS_32BIT;
        ref_clk_sel = AT112G_REFCLK_SELGROUP1;
        ref_freq = AT112G_REFFREQ156P25MHZ;
    }

    _sys_at_serdes_to_dev(lchip, serdes_id, ip_type, &dev);   
    txrx_speed = _sys_at_serdes_get_related_txrx_speed(serdes_speed, ip_type);
    
    /* Configure Reference Frequency and reference clock source group for all lanes */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set Reference Frequency start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_ref_freq(&dev, ref_freq, ref_freq, 
        ref_clk_sel, ref_clk_sel));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Set Reference Frequency end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====7. Set TX and RX bitrates start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====7. Set TX and RX bitrates end\n");

    /* Set Data Bus Width for all lanes */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====10 Set Data Bus Width start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_data_width(&dev, data_width, data_width));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====10. Set Data Bus Width end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====10a. Set gray code & precode start\n");
    if(AT_IS_SERDES_SPEED_PAM4(serdes_speed))
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, TRUE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, TRUE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_RX, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_TX, FALSE));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_RX, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_TX, FALSE));
    }
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====10a. Set gray code & precode end\n");

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_polarity(lchip, serdes_id, &tx_pol, &rx_pol));
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, serdes_id, DMPS_TX, tx_pol));
    CTC_ERROR_RETURN(_sys_at_serdes_set_polarity(lchip, serdes_id, DMPS_RX, rx_pol));

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====11. Power on PHY PLLs, TX and RX start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, TRUE));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====11. Power on PHY PLLs, TX and RX end\n");

    /* Wait HssRx/Tx Rst Ack */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====12. Wait TX/RX Rst Ack start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_tx_rstdone(&dev, 1));
    CTC_ERROR_RETURN(_sys_at_serdes_wait_rx_rstdone(&dev, 1));
#ifdef AT_SERDES_SIM
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 220000\n");
#endif
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====12. Wait TX/RX Rst Ack end\n");
    
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====13. Release TX/RX Rst start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, FALSE));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====13. Release TX/RX Rst start\n");
    
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====14. Wait TX/RX PLL Ready start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));
#ifdef AT_SERDES_SIM
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 200000\n");
#endif
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====14. Wait TX/RX PLL Ready end\n");      
    ///TODO: BRINGUP 1 NORMAL 0
    /* Enable TX Output for all lanes */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====15. Enable TX Output start\n");
    //if (is_tx_en)
    {
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, TRUE));
    }
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====15. Enable TX Output end\n");

    /* Toggle RX_INIT */
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====16. Toggle RX_INIT start\n");
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));
    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====16. Toggle RX_INIT end\n");

    SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// power on per lane end , serdes %d !!!\n", serdes_id);

    return CTC_E_NONE;
}

int32 _sys_at_serdes_speed_switch_proc(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    sys_at_serdes_dev_t dev = {0};
#ifndef AT_SERDES_SIM        
    uint8  ip_type = _sys_at_datapath_get_serdes_type(serdes_id);
#else
    uint8  ip_type = temp_soft_table[0].ip_type;
#endif
    uint32 txrx_speed = _sys_at_serdes_get_related_txrx_speed(serdes_speed, ip_type);

    sal_printf("==== serdes %u switch start\n", serdes_id);

    _sys_at_serdes_to_dev(lchip, serdes_id, ip_type, &dev);

    if(SERDES_SPEED_0G == serdes_speed)
    {
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u switch to none start\n", serdes_id);
        /* Make sure PHY PLLs, Transmitter and Receiver powered is off for all lanes */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Power off start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, FALSE));
        CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, TRUE));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====1. Power off end\n");
        /*. Disable TX Output for all lanes */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Disable TX Output start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, FALSE));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====2. Disable TX Output end\n");
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u switch to none end\n", serdes_id);
        
    }
    else
    {
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u switch to speed%u start\n", serdes_id, serdes_speed);
        /* Configure TX and RX bitrates for all lanes */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set TX and RX bitrates start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3. Set TX and RX bitrates end\n");
    
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3a. Set gray code & precode start\n");
        if(AT_IS_SERDES_SPEED_PAM4(_sys_at_serdes_get_related_serdes_speed(txrx_speed, ip_type)))
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, TRUE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, TRUE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_RX, FALSE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_TX, FALSE));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_RX, FALSE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_graycode_en(lchip, serdes_id, DMPS_TX, FALSE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_RX, FALSE));
            CTC_ERROR_RETURN(_sys_at_serdes_set_precode_en(lchip, serdes_id, DMPS_TX, FALSE));
        }
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====3a. Set gray code & precode end\n");
    
        /* Wait TX/RX Rst Ack */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Wait TX/RX Rst Ack start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_wait_rx_rstdone(&dev, 1));
        CTC_ERROR_RETURN(_sys_at_serdes_wait_tx_rstdone(&dev, 1));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====4. Wait TX/RX Rst Ack end\n");
    
        #ifdef AT_SERDES_SIM
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 10000\n");
        #endif
    
        /* Release tx/rx reset */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Release tx&rx reset start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_reset(&dev, 0));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====5. Release tx&rx reset end\n");
        
        /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Power on PHY PLLs, TX and RX start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_lane_power(&dev, TRUE));
        CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====6. Power on PHY PLLs, TX and RX end\n");
    
        #ifdef AT_SERDES_SIM
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"sleep 200000\n");
        #endif
    
        /* Enable TX Output for all lanes */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====7. Enable TX Output start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 1));
    
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====7. Enable TX Output end\n");
    
        /* Toggle RX_INIT */
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====8. Toggle RX_INIT start\n");
        CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ====8. Toggle RX_INIT end\n");
        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp,"// ==== serdes %u switch to speed%u end\n", serdes_id, serdes_speed);
  }

    return CTC_E_NONE;
}
#endif

#if 0
int32 _sys_at_serdes_speed_switch_simplify(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    sys_at_serdes_dev_t dev = {0};
    uint8 txrx_speed = _sys_at_serdes_get_related_txrx_speed(serdes_speed, ip_type);

    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);

    /* Disable TX Output for all lanes */
    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 0));
    
    /* Configure TX and RX bitrates for all lanes */
    CTC_ERROR_RETURN(_sys_at_serdes_set_txrx_bit_rate(&dev, txrx_speed, txrx_speed));

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    CTC_ERROR_RETURN(_sys_at_serdes_wait_pll_ready(&dev));
    
    /* Enable TX Output for all lanes */
    CTC_ERROR_RETURN(_sys_at_serdes_set_tx_en(&dev, 1));

    /* Toggle RX_INIT */
    CTC_ERROR_RETURN(_sys_at_serdes_set_rx_init(&dev));

    return CTC_E_NONE;
}
#endif

int32
sys_at_serdes_get_link_training_status(uint8 lchip, uint16 serdes_id, uint16* p_value)
{
    uint16 stat = 0;
    sys_at_serdes_dev_t dev = {0};
    _sys_at_get_serdes_dev(lchip, serdes_id, &dev);
    CTC_ERROR_RETURN(_sys_at_serdes_get_training_status(&dev, &stat));
    SYS_USW_VALID_PTR_WRITE(p_value, stat);

    return CTC_E_NONE;
}

int32
sys_at_serdes_serdes_to_psd(uint8 lchip, uint16 serdes_id, uint16* psd)
{
    uint8 mac_group_id = 0;
    CTC_PTR_VALID_CHECK(psd);

    if (DMPS_INVALID_VALUE_U16 == serdes_id)
    {
        *psd = DMPS_INVALID_VALUE_U16;
        return CTC_E_NONE;
    }

    mac_group_id = (serdes_id / AT_SERDES_NUM_PER_MCMAC) % AT_MCMAC_NUM_PER_CORE;
    if (mac_group_id < SYS_AT_MAC_GROUP_NUM_HALF_CORE)
    {
        *psd = serdes_id;
    }
    else
    {
        *psd = (serdes_id % AT_SERDES_NUM_PER_MCMAC < AT_SERDES_NUM_PER_HSS) ?
            (serdes_id + AT_SERDES_NUM_PER_HSS) : (serdes_id - AT_SERDES_NUM_PER_HSS);
    }

    return CTC_E_NONE;
}

int32
sys_at_serdes_psd_to_serdes(uint8 lchip, uint16 psd, uint16* serdes_id)
{
    uint8 mac_group_id = 0;
    CTC_PTR_VALID_CHECK(serdes_id);

    if (DMPS_INVALID_VALUE_U16 == psd)
    {
        *serdes_id = DMPS_INVALID_VALUE_U16;
        return CTC_E_NONE;
    }

    mac_group_id = (psd / AT_SERDES_NUM_PER_MCMAC) % AT_MCMAC_NUM_PER_CORE;
    if (mac_group_id < SYS_AT_MAC_GROUP_NUM_HALF_CORE)
    {
        *serdes_id = psd;
    }
    else
    {
        *serdes_id = (psd % AT_SERDES_NUM_PER_MCMAC < AT_SERDES_NUM_PER_HSS) ?
            (psd + AT_SERDES_NUM_PER_HSS) : (psd - AT_SERDES_NUM_PER_HSS);
    }

    return CTC_E_NONE;
}

